unfairly 0.8.1 → 0.8.3

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 (89) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +17 -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 +101 -0
  10. package/dist/cmd/pace.d.ts.map +1 -0
  11. package/dist/cmd/pace.js +426 -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 +104 -0
  21. package/dist/pace/device.d.ts.map +1 -0
  22. package/dist/pace/device.js +149 -0
  23. package/dist/pace/device.js.map +1 -0
  24. package/dist/pace/enroll.d.ts +80 -0
  25. package/dist/pace/enroll.d.ts.map +1 -0
  26. package/dist/pace/enroll.js +138 -0
  27. package/dist/pace/enroll.js.map +1 -0
  28. package/dist/pace/identity.d.ts +10 -0
  29. package/dist/pace/identity.d.ts.map +1 -0
  30. package/dist/pace/identity.js +17 -0
  31. package/dist/pace/identity.js.map +1 -0
  32. package/dist/pace/install.d.ts +28 -0
  33. package/dist/pace/install.d.ts.map +1 -0
  34. package/dist/pace/install.js +127 -0
  35. package/dist/pace/install.js.map +1 -0
  36. package/dist/pace/local-evidence.d.ts +75 -0
  37. package/dist/pace/local-evidence.d.ts.map +1 -0
  38. package/dist/pace/local-evidence.js +228 -0
  39. package/dist/pace/local-evidence.js.map +1 -0
  40. package/dist/pace/local-sessions.d.ts +48 -0
  41. package/dist/pace/local-sessions.d.ts.map +1 -0
  42. package/dist/pace/local-sessions.js +254 -0
  43. package/dist/pace/local-sessions.js.map +1 -0
  44. package/dist/pace/managed-config.d.ts +21 -0
  45. package/dist/pace/managed-config.d.ts.map +1 -0
  46. package/dist/pace/managed-config.js +102 -0
  47. package/dist/pace/managed-config.js.map +1 -0
  48. package/dist/pace/normalize.d.ts +10 -0
  49. package/dist/pace/normalize.d.ts.map +1 -0
  50. package/dist/pace/normalize.js +293 -0
  51. package/dist/pace/normalize.js.map +1 -0
  52. package/dist/pace/repository.d.ts +72 -0
  53. package/dist/pace/repository.d.ts.map +1 -0
  54. package/dist/pace/repository.js +120 -0
  55. package/dist/pace/repository.js.map +1 -0
  56. package/dist/pace/schema.d.ts +1325 -0
  57. package/dist/pace/schema.d.ts.map +1 -0
  58. package/dist/pace/schema.js +134 -0
  59. package/dist/pace/schema.js.map +1 -0
  60. package/dist/pace/session-summary.d.ts +179 -0
  61. package/dist/pace/session-summary.d.ts.map +1 -0
  62. package/dist/pace/session-summary.js +140 -0
  63. package/dist/pace/session-summary.js.map +1 -0
  64. package/dist/pace/spool.d.ts +6 -0
  65. package/dist/pace/spool.d.ts.map +1 -0
  66. package/dist/pace/spool.js +87 -0
  67. package/dist/pace/spool.js.map +1 -0
  68. package/dist/pace-runtime.d.ts +2 -0
  69. package/dist/pace-runtime.d.ts.map +1 -0
  70. package/dist/pace-runtime.js +67 -0
  71. package/dist/pace-runtime.js.map +1 -0
  72. package/package.json +5 -2
  73. package/plugin/.claude-plugin/plugin.json +9 -0
  74. package/plugin/.codex-plugin/plugin.json +21 -0
  75. package/plugin/.cursor-plugin/plugin.json +16 -0
  76. package/plugin/.mcp.json +8 -0
  77. package/plugin/README.md +15 -0
  78. package/plugin/deploy/README.md +30 -0
  79. package/plugin/gemini/GEMINI.md +3 -0
  80. package/plugin/gemini/gemini-extension.json +12 -0
  81. package/plugin/gemini/hooks/hooks.json +52 -0
  82. package/plugin/hooks/cursor-hooks.json +25 -0
  83. package/plugin/hooks/hooks.json +56 -0
  84. package/plugin/mcp.json +10 -0
  85. package/plugin/plugin.json +32 -0
  86. package/plugin/runtime/unfairly-intelligence.mjs +5513 -0
  87. package/plugin/scripts/capture.cjs +68 -0
  88. package/plugin/skills/find-company-playbook/SKILL.md +12 -0
  89. package/plugin/skills/publish-learning/SKILL.md +8 -0
@@ -0,0 +1,67 @@
1
+ /**
2
+ * The runtime bundled inside the Unfairly plugin (plugins/ai-pace/runtime), so
3
+ * installing the plugin from an AI client's plugin store is the whole install:
4
+ * no npm, no terminal. Hooks call it as `node unfairly-intelligence.mjs <command>`.
5
+ *
6
+ * connect <source> <event> first-run connection; prints the SessionStart message
7
+ * await-approval background: claims the credential once the person approves, then syncs
8
+ * capture <source> <event> record a hook event (reads the hook payload on stdin)
9
+ */
10
+ import { spawn } from "node:child_process";
11
+ import os from "node:os";
12
+ import { runPaceCapture, runPaceSync } from "./cmd/pace.js";
13
+ import { readOrCreatePaceDevice } from "./pace/device.js";
14
+ import { acquireApprovalLock, awaitApproval, ensureEnrolled, releaseApprovalLock, sessionStartOutput } from "./pace/enroll.js";
15
+ const DEFAULT_API = "https://app.unfairly.ai";
16
+ const apiUrl = () => (process.env.UNFAIRLY_API_URL ?? DEFAULT_API).replace(/\/$/, "");
17
+ async function connect(source, event) {
18
+ const device = await readOrCreatePaceDevice();
19
+ if (device.paused)
20
+ return;
21
+ const platform = os.platform();
22
+ const arch = os.arch();
23
+ if ((platform !== "darwin" && platform !== "linux" && platform !== "win32") || (arch !== "x64" && arch !== "arm64"))
24
+ return;
25
+ const state = await ensureEnrolled({
26
+ apiUrl: apiUrl(),
27
+ installationId: device.installation_id,
28
+ platform,
29
+ arch,
30
+ // The calling client identifies itself; probing every installed tool is too slow for a session start.
31
+ clients: [source],
32
+ orgHint: process.env.UNFAIRLY_ORG,
33
+ });
34
+ const output = sessionStartOutput(state, event === "sessionStart" ? "sessionStart" : "SessionStart");
35
+ if (output)
36
+ process.stdout.write(`${output}\n`);
37
+ if (state.status === "waiting") {
38
+ // Watch for the approval in the background so the machine connects while
39
+ // this session is still open. Detached, so the session never waits on it.
40
+ const child = spawn(process.execPath, [process.argv[1], "await-approval"], { detached: true, stdio: "ignore", env: process.env });
41
+ child.on("error", () => undefined);
42
+ child.unref();
43
+ }
44
+ }
45
+ async function awaitApprovalAndSync() {
46
+ if (!(await acquireApprovalLock()))
47
+ return;
48
+ try {
49
+ if (await awaitApproval({ apiUrl: apiUrl() }))
50
+ await runPaceSync();
51
+ }
52
+ finally {
53
+ await releaseApprovalLock();
54
+ }
55
+ }
56
+ async function main() {
57
+ const [command, source = "unknown", event = "Unknown"] = process.argv.slice(2);
58
+ if (command === "connect")
59
+ await connect(source, event);
60
+ else if (command === "await-approval")
61
+ await awaitApprovalAndSync();
62
+ else if (command === "capture")
63
+ await runPaceCapture(source, event);
64
+ }
65
+ // Telemetry must never break the person's AI session.
66
+ main().catch(() => undefined).finally(() => process.exit(0));
67
+ //# sourceMappingURL=pace-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pace-runtime.js","sourceRoot":"","sources":["../src/pace-runtime.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.3",
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,7 +53,9 @@
53
53
  "build": "tsc && chmod +x dist/index.js",
54
54
  "dev": "tsx src/index.ts",
55
55
  "test": "vitest run",
56
- "prepublishOnly": "npm run build"
56
+ "prepack": "npm run build && node scripts/bundle-plugin-runtime.mjs && node scripts/stage-intelligence-plugin.mjs",
57
+ "prepublishOnly": "npm run build",
58
+ "bundle:plugin-runtime": "node scripts/bundle-plugin-runtime.mjs"
57
59
  },
58
60
  "dependencies": {
59
61
  "@modelcontextprotocol/sdk": "^1.0.4",
@@ -76,6 +78,7 @@
76
78
  },
77
79
  "files": [
78
80
  "dist",
81
+ "plugin",
79
82
  "README.md",
80
83
  "CHANGELOG.md"
81
84
  ]
@@ -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
+ }
@@ -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.3", "mcp"]
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,15 @@
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 carries its own bundled runtime (`runtime/unfairly-intelligence.mjs`, generated from `cli/src/pace-runtime.ts` by `npm run bundle:plugin-runtime` in `cli/`), so installing the plugin is the whole install. Hooks call `scripts/capture.cjs`, which prefers the bundled runtime and falls back to a runtime placed by `npx unfairly` or a global `unfairly`. Identity, redaction, Git enrichment, durable local spooling, upload, and policy live in the shared CLI core.
6
+
7
+ Employees install it from their AI client's plugin screen, using the public marketplace `Unfairly-AI/unfairly-intelligence` (built from this directory by `scripts/build-intelligence-marketplace.mjs`). An administrator sends them `https://intelligence.unfairly.ai/install?org=<org-id>`, which walks through each client and shows the Claude managed-settings snippet for pushing it to everyone. On the first session start the plugin prints a link; the employee approves the machine in the browser (choosing the organization if they belong to several), and the machine receives its own revocable collector credential. A background poller picks up the approval within a few seconds, so the same session connects, and the first sync uploads the last 90 days of sessions after fetching the approved-repository list. After that, session summaries upload at every session start and end.
8
+
9
+ The terminal path still works: `npx unfairly@latest setup --org <org-id>` installs and enrolls, and `unfairly intelligence backfill --days 90` uploads past sessions from the local transcripts.
10
+
11
+ 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.
12
+
13
+ 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.
14
+
15
+ 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.3", "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.3", "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
+ }