unfairly 0.8.0 → 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 (83) hide show
  1. package/CHANGELOG.md +12 -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/pull.d.ts.map +1 -1
  14. package/dist/cmd/pull.js +23 -1
  15. package/dist/cmd/pull.js.map +1 -1
  16. package/dist/cmd/setup.d.ts +2 -0
  17. package/dist/cmd/setup.d.ts.map +1 -1
  18. package/dist/cmd/setup.js +20 -6
  19. package/dist/cmd/setup.js.map +1 -1
  20. package/dist/index.js +96 -2
  21. package/dist/index.js.map +1 -1
  22. package/dist/lib/types/index.d.ts +6 -6
  23. package/dist/pace/device.d.ts +101 -0
  24. package/dist/pace/device.d.ts.map +1 -0
  25. package/dist/pace/device.js +148 -0
  26. package/dist/pace/device.js.map +1 -0
  27. package/dist/pace/identity.d.ts +10 -0
  28. package/dist/pace/identity.d.ts.map +1 -0
  29. package/dist/pace/identity.js +17 -0
  30. package/dist/pace/identity.js.map +1 -0
  31. package/dist/pace/install.d.ts +28 -0
  32. package/dist/pace/install.d.ts.map +1 -0
  33. package/dist/pace/install.js +127 -0
  34. package/dist/pace/install.js.map +1 -0
  35. package/dist/pace/local-evidence.d.ts +75 -0
  36. package/dist/pace/local-evidence.d.ts.map +1 -0
  37. package/dist/pace/local-evidence.js +228 -0
  38. package/dist/pace/local-evidence.js.map +1 -0
  39. package/dist/pace/local-sessions.d.ts +48 -0
  40. package/dist/pace/local-sessions.d.ts.map +1 -0
  41. package/dist/pace/local-sessions.js +254 -0
  42. package/dist/pace/local-sessions.js.map +1 -0
  43. package/dist/pace/managed-config.d.ts +21 -0
  44. package/dist/pace/managed-config.d.ts.map +1 -0
  45. package/dist/pace/managed-config.js +102 -0
  46. package/dist/pace/managed-config.js.map +1 -0
  47. package/dist/pace/normalize.d.ts +10 -0
  48. package/dist/pace/normalize.d.ts.map +1 -0
  49. package/dist/pace/normalize.js +293 -0
  50. package/dist/pace/normalize.js.map +1 -0
  51. package/dist/pace/repository.d.ts +72 -0
  52. package/dist/pace/repository.d.ts.map +1 -0
  53. package/dist/pace/repository.js +120 -0
  54. package/dist/pace/repository.js.map +1 -0
  55. package/dist/pace/schema.d.ts +1325 -0
  56. package/dist/pace/schema.d.ts.map +1 -0
  57. package/dist/pace/schema.js +134 -0
  58. package/dist/pace/schema.js.map +1 -0
  59. package/dist/pace/session-summary.d.ts +179 -0
  60. package/dist/pace/session-summary.d.ts.map +1 -0
  61. package/dist/pace/session-summary.js +140 -0
  62. package/dist/pace/session-summary.js.map +1 -0
  63. package/dist/pace/spool.d.ts +6 -0
  64. package/dist/pace/spool.d.ts.map +1 -0
  65. package/dist/pace/spool.js +87 -0
  66. package/dist/pace/spool.js.map +1 -0
  67. package/package.json +3 -1
  68. package/plugin/.claude-plugin/plugin.json +9 -0
  69. package/plugin/.codex-plugin/plugin.json +21 -0
  70. package/plugin/.cursor-plugin/plugin.json +16 -0
  71. package/plugin/.mcp.json +8 -0
  72. package/plugin/README.md +19 -0
  73. package/plugin/deploy/README.md +30 -0
  74. package/plugin/gemini/GEMINI.md +3 -0
  75. package/plugin/gemini/gemini-extension.json +12 -0
  76. package/plugin/gemini/hooks/hooks.json +52 -0
  77. package/plugin/hooks/cursor-hooks.json +25 -0
  78. package/plugin/hooks/hooks.json +56 -0
  79. package/plugin/mcp.json +10 -0
  80. package/plugin/plugin.json +32 -0
  81. package/plugin/scripts/capture.cjs +46 -0
  82. package/plugin/skills/find-company-playbook/SKILL.md +12 -0
  83. package/plugin/skills/publish-learning/SKILL.md +8 -0
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "ai-pace",
3
+ "version": "0.1.0+codex.20260923193801",
4
+ "description": "Organizational intelligence for AI-enabled work, with content-free evidence and reusable team playbooks.",
5
+ "author": {
6
+ "name": "Unfairly"
7
+ },
8
+ "skills": "./skills/",
9
+ "interface": {
10
+ "displayName": "Unfairly Intelligence",
11
+ "shortDescription": "See what works. Help your company learn.",
12
+ "longDescription": "Unfairly Intelligence captures a narrow, content-free set of workflow and approved output facts across supported AI clients, connects aggregate investment to evidence and outcomes, and returns approved methods through a company marketplace.",
13
+ "developerName": "Unfairly",
14
+ "category": "Productivity",
15
+ "capabilities": [
16
+ "Interactive"
17
+ ],
18
+ "defaultPrompt": "Show me the most relevant approved company playbooks for this work."
19
+ },
20
+ "mcpServers": "./.mcp.json"
21
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "ai-pace",
3
+ "version": "0.1.0",
4
+ "description": "Unfairly Intelligence: content-free workflow evidence and reusable company playbooks.",
5
+ "author": {
6
+ "name": "Unfairly",
7
+ "email": "bob@hq.unfairly.ai"
8
+ },
9
+ "homepage": "https://intelligence.unfairly.ai",
10
+ "repository": "https://github.com/Unfairly-AI/unfairly-app",
11
+ "license": "MIT",
12
+ "keywords": ["analytics", "developer-tools", "governance", "playbooks"],
13
+ "skills": "./skills/",
14
+ "hooks": "./hooks/cursor-hooks.json",
15
+ "mcpServers": "./mcp.json"
16
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "unfairly": {
4
+ "command": "npx",
5
+ "args": ["-y", "unfairly@0.8.2", "mcp"]
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,19 @@
1
+ # Unfairly plugin for Unfairly Intelligence
2
+
3
+ The Unfairly plugin is the portable workflow component for Unfairly Intelligence, backed by the existing `unfairly` CLI. Its root Agent Plugins manifest carries the shared skills and MCP definition. Codex/ChatGPT Work use the OpenAI extension, Claude Code uses the Claude compatibility manifest, Cursor uses the native Cursor overlay, and Gemini CLI loads the nested `gemini/` extension. All lifecycle hooks call the compatibility command `unfairly pace capture` and emit the same content-free event contract. Employee-facing commands use `unfairly intelligence`.
4
+
5
+ The plugin intentionally contains only thin compatibility manifests. Identity, redaction, Git enrichment, durable local spooling, upload, and policy live in the shared CLI core.
6
+
7
+ Employees install it through the existing one-command path:
8
+
9
+ ```bash
10
+ npx unfairly@latest
11
+ ```
12
+
13
+ The command places a version-pinned runtime and marketplace under `~/.unfairly`, activates every detected hook-capable client, and confirms enrollment with the Intelligence API. No global npm install or administrator permission is required. A newly installed AI client is picked up the next time the command runs. `unfairly intelligence install` is the explicit repair/reinstall command.
14
+
15
+ Before activation, inspect the exact contract with `unfairly intelligence policy`. Use `unfairly intelligence status` to see enabled clients, queue depth, policy/runtime/plugin versions, attestation expiry, and last upload. Collection can be stopped without losing installation identity with `unfairly intelligence pause` and restarted with `unfairly intelligence resume`. `unfairly intelligence uninstall` removes only tracked Unfairly-managed files and local Intelligence state.
16
+
17
+ It also closes the learning loop. Employees can search the organization's approved marketplace with `unfairly intelligence playbooks --query "<goal>"`, start one with `unfairly intelligence playbook-use <playbook-id> --version <version>`, and propose a content-safe learning after successful work. Playbook identity and version travel with workflow evidence so the dashboard can distinguish discovery, installation, reuse, and verified outcomes.
18
+
19
+ The same runtime now includes a local evidence adapter for ChatGPT Desktop, Claude Desktop, and other closed applications. A centrally managed allowlist defines which output or app-state directories may be observed. Output roots produce content-free created/modified artifact facts; app-state roots produce one aggregated activity fact per scan. The adapter never reads file contents, silently expands beyond approved roots, or emits filenames.
@@ -0,0 +1,30 @@
1
+ # Centrally managed deployment
2
+
3
+ The portable plugin is the employee-facing package. The `unfairly` runtime is the managed enforcement and telemetry component.
4
+
5
+ Generate vendor configuration from the same shared event definition:
6
+
7
+ ```bash
8
+ unfairly intelligence config \
9
+ --output ./ai-pace-managed \
10
+ --command /usr/local/bin/unfairly \
11
+ --managed-dir /usr/local/lib/ai-pace \
12
+ --evidence-root "/Users/Shared/AI Outputs"
13
+ ```
14
+
15
+ Deploy the generated files through Jamf, Kandji, Intune, Fleet, or an equivalent endpoint manager:
16
+
17
+ - `codex-requirements.toml` to `/etc/codex/requirements.toml` on macOS/Linux or `%ProgramData%\OpenAI\Codex\requirements.toml` on Windows.
18
+ - Merge `claude-settings.json` into the organization-managed Claude Code settings layer.
19
+ - Deploy `cursor-hooks.json` as the Cursor enterprise/team hook configuration, or to `~/.cursor/hooks.json` for a pilot user.
20
+ - Merge `gemini-settings.json` into `/Library/Application Support/GeminiCli/settings.json`, `/etc/gemini-cli/settings.json`, or `C:\ProgramData\gemini-cli\settings.json` according to platform.
21
+ - Install the `unfairly` executable at the exact absolute command path used during generation.
22
+ - Schedule `unfairly intelligence heartbeat` at login and every five minutes. It reports coverage and refreshes the short-lived device attestation.
23
+ - Deploy `evidence-policy.json` to a root-owned managed path, then run `unfairly intelligence evidence-watch --policy <managed-path>` as a user launch agent or managed background process.
24
+ - Populate `repository-policy.json` only with SHA-256 remote fingerprints and organization-issued repository UUIDs, then deploy it to the managed path named by `UNFAIRLY_PACE_REPOSITORY_POLICY`. The collector compares remotes locally and never emits a remote, path, repository name, or branch.
25
+
26
+ The generated policy treats every `--evidence-root` as an approved work-output directory. Administrators may also add an `app_state` root with `source_app` set to `chatgpt` or `claude_desktop`. App-state roots emit aggregate change activity only; they do not expose cache filenames or contents. File basenames are never emitted.
27
+
28
+ Do not place API keys, employee tokens, provider credentials, prompt logging, response logging, home-directory-wide roots, or unreviewed application caches in managed configuration. Authentication remains in the employee OS keychain.
29
+
30
+ Validate each enrolled machine with `unfairly intelligence policy`, `unfairly intelligence status`, and one explicit `unfairly intelligence flush`. To stop collection temporarily, use the local pause command or set the installation to paused in Governance. Revoke an installation when its token or device is no longer trusted. Uninstall removes only the managed files recorded in local installation state; the endpoint manager remains responsible for removing centrally deployed copies.
@@ -0,0 +1,3 @@
1
+ # Unfairly Intelligence
2
+
3
+ The Unfairly plugin is installed by your organization so teams can learn from content-free workflow evidence, connect AI investment to outcomes, and share reusable methods. Use the Unfairly MCP server for approved organizational context and playbooks. Never send prompt bodies, response bodies, file contents, secrets, or raw command output to telemetry.
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "ai-pace",
3
+ "version": "0.1.0",
4
+ "description": "Managed, content-safe AI usage telemetry and reusable team playbooks.",
5
+ "contextFileName": "GEMINI.md",
6
+ "mcpServers": {
7
+ "unfairly": {
8
+ "command": "npx",
9
+ "args": ["-y", "unfairly@0.8.2", "mcp"]
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "hooks": {
3
+ "SessionStart": [
4
+ {
5
+ "matcher": "*",
6
+ "hooks": [
7
+ {
8
+ "name": "ai-pace-session-start",
9
+ "type": "command",
10
+ "command": "unfairly pace capture --source gemini_cli --event SessionStart"
11
+ }
12
+ ]
13
+ }
14
+ ],
15
+ "AfterTool": [
16
+ {
17
+ "matcher": "*",
18
+ "hooks": [
19
+ {
20
+ "name": "ai-pace-after-tool",
21
+ "type": "command",
22
+ "command": "unfairly pace capture --source gemini_cli --event AfterTool"
23
+ }
24
+ ]
25
+ }
26
+ ],
27
+ "AfterModel": [
28
+ {
29
+ "matcher": "*",
30
+ "hooks": [
31
+ {
32
+ "name": "ai-pace-after-model",
33
+ "type": "command",
34
+ "command": "unfairly pace capture --source gemini_cli --event AfterModel"
35
+ }
36
+ ]
37
+ }
38
+ ],
39
+ "SessionEnd": [
40
+ {
41
+ "matcher": "*",
42
+ "hooks": [
43
+ {
44
+ "name": "ai-pace-session-end",
45
+ "type": "command",
46
+ "command": "unfairly pace capture --source gemini_cli --event SessionEnd"
47
+ }
48
+ ]
49
+ }
50
+ ]
51
+ }
52
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "version": 1,
3
+ "hooks": {
4
+ "sessionStart": [
5
+ {
6
+ "command": "node \"${CURSOR_PLUGIN_ROOT}/scripts/capture.cjs\" sessionStart"
7
+ }
8
+ ],
9
+ "postToolUse": [
10
+ {
11
+ "command": "node \"${CURSOR_PLUGIN_ROOT}/scripts/capture.cjs\" postToolUse"
12
+ }
13
+ ],
14
+ "postToolUseFailure": [
15
+ {
16
+ "command": "node \"${CURSOR_PLUGIN_ROOT}/scripts/capture.cjs\" postToolUseFailure"
17
+ }
18
+ ],
19
+ "sessionEnd": [
20
+ {
21
+ "command": "node \"${CURSOR_PLUGIN_ROOT}/scripts/capture.cjs\" sessionEnd"
22
+ }
23
+ ]
24
+ }
25
+ }
@@ -0,0 +1,56 @@
1
+ {
2
+ "hooks": {
3
+ "SessionStart": [
4
+ {
5
+ "hooks": [
6
+ {
7
+ "type": "command",
8
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/capture.cjs\" SessionStart"
9
+ }
10
+ ]
11
+ }
12
+ ],
13
+ "PostToolUse": [
14
+ {
15
+ "matcher": "*",
16
+ "hooks": [
17
+ {
18
+ "type": "command",
19
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/capture.cjs\" PostToolUse"
20
+ }
21
+ ]
22
+ }
23
+ ],
24
+ "PostToolUseFailure": [
25
+ {
26
+ "matcher": "*",
27
+ "hooks": [
28
+ {
29
+ "type": "command",
30
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/capture.cjs\" PostToolUseFailure"
31
+ }
32
+ ]
33
+ }
34
+ ],
35
+ "Stop": [
36
+ {
37
+ "hooks": [
38
+ {
39
+ "type": "command",
40
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/capture.cjs\" Stop"
41
+ }
42
+ ]
43
+ }
44
+ ],
45
+ "SessionEnd": [
46
+ {
47
+ "hooks": [
48
+ {
49
+ "type": "command",
50
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/scripts/capture.cjs\" SessionEnd"
51
+ }
52
+ ]
53
+ }
54
+ ]
55
+ }
56
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
3
+ "mcpServers": {
4
+ "unfairly": {
5
+ "type": "stdio",
6
+ "command": "npx",
7
+ "args": ["-y", "unfairly@0.8.2", "mcp"]
8
+ }
9
+ }
10
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
3
+ "name": "ai-pace",
4
+ "version": "0.1.0",
5
+ "description": "Unfairly Intelligence: content-free workflow evidence and reusable company playbooks across AI coding agents.",
6
+ "author": {
7
+ "name": "Unfairly",
8
+ "email": "bob@hq.unfairly.ai",
9
+ "url": "https://unfairly.ai"
10
+ },
11
+ "homepage": "https://intelligence.unfairly.ai",
12
+ "repository": "https://github.com/Unfairly-AI/unfairly-app",
13
+ "license": "MIT",
14
+ "keywords": ["analytics", "developer-tools", "governance", "playbooks"],
15
+ "extensions": {
16
+ "com.openai": {
17
+ "hooks": "./hooks/hooks.json",
18
+ "interface": {
19
+ "displayName": "Unfairly Intelligence",
20
+ "shortDescription": "See what works. Help your company learn.",
21
+ "longDescription": "Collect content-free workflow evidence across supported coding agents and return approved company playbooks to employees.",
22
+ "developerName": "Unfairly",
23
+ "category": "Productivity",
24
+ "capabilities": ["Interactive"],
25
+ "websiteURL": "https://intelligence.unfairly.ai",
26
+ "defaultPrompt": [
27
+ "Show me the most relevant approved company playbooks for this work."
28
+ ]
29
+ }
30
+ }
31
+ }
32
+ }
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env node
2
+ const { spawn } = require("node:child_process");
3
+ const fs = require("node:fs");
4
+ const os = require("node:os");
5
+ const path = require("node:path");
6
+
7
+ const event = process.argv[2] || process.env.HOOK_EVENT_NAME || "Unknown";
8
+ const source = process.env.GEMINI_CLI_HOME
9
+ ? "gemini_cli"
10
+ : process.env.CURSOR_PLUGIN_ROOT || process.env.CURSOR_PROJECT_DIR
11
+ ? "cursor"
12
+ : process.env.PLUGIN_ROOT
13
+ ? "codex"
14
+ : "claude_code";
15
+
16
+ let command = "unfairly";
17
+ let args = ["pace", "capture", "--source", source, "--event", event];
18
+ try {
19
+ const pointer = JSON.parse(fs.readFileSync(path.join(os.homedir(), ".unfairly", "runtime", "current.json"), "utf8"));
20
+ if (typeof pointer.node === "string" && typeof pointer.entrypoint === "string") {
21
+ command = pointer.node;
22
+ args = [pointer.entrypoint, ...args];
23
+ }
24
+ } catch {
25
+ // Compatibility fallback for existing global installs.
26
+ }
27
+
28
+ // Read the hook payload, hand it to a detached runtime process, and return at
29
+ // once: summarizing transcripts and uploading must never make the AI client wait.
30
+ const chunks = [];
31
+ process.stdin.on("data", (chunk) => chunks.push(chunk));
32
+ process.stdin.on("error", () => process.exit(0));
33
+ process.stdin.on("end", () => {
34
+ let child;
35
+ try {
36
+ child = spawn(command, args, { stdio: ["pipe", "ignore", "ignore"], env: process.env, detached: true });
37
+ } catch {
38
+ process.exit(0);
39
+ }
40
+ child.on("error", () => process.exit(0));
41
+ child.stdin.on("error", () => undefined);
42
+ child.stdin.end(Buffer.concat(chunks), () => {
43
+ child.unref();
44
+ process.exit(0);
45
+ });
46
+ });
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: find-company-playbook
3
+ description: Find and apply an approved company playbook when an employee asks how the organization handles a task, wants a reusable workflow, or starts work that may match an existing method.
4
+ ---
5
+
6
+ # Find a company playbook
7
+
8
+ Search the approved Unfairly Intelligence marketplace with `unfairly intelligence playbooks --query "<employee goal>"` before inventing a new workflow. Prefer a published playbook; label a pilot-ready playbook as a pilot.
9
+
10
+ Show the employee the playbook title, intended outcome, owner, source requirements, and ordered steps. Ask before taking consequential actions. When the playbook is used, preserve its identifier and version in Unfairly Intelligence workflow context so reuse and downstream outcomes can be measured.
11
+
12
+ Never expose another employee's prompts, responses, files, source code, or private session history. If no playbook matches, complete the work normally and offer to propose the successful method as a new learning.
@@ -0,0 +1,8 @@
1
+ ---
2
+ name: publish-learning
3
+ description: Propose a reusable, content-safe team playbook from a successful workflow when the user asks to share or publish a learning.
4
+ ---
5
+
6
+ # Publish an Unfairly Intelligence learning
7
+
8
+ Summarize the reusable workflow, not the private work product. Include the goal, tools and skills used, ordered steps, verification method, common failures, and resulting artifact type. Exclude prompts, responses, secrets, source code, customer data, file contents, and raw command output. Ask the employee to approve the proposed playbook before publishing it through Unfairly.