humanlypossible 0.1.1 → 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 +40 -0
- package/dist/cli.js +84 -3
- package/dist/mcp-7IK2TXZV.js +851 -0
- package/dist/mcp.js +851 -0
- package/package.json +12 -8
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# humanlypossible
|
|
2
|
+
|
|
3
|
+
**The outcome protocol for delegating real-world tasks from AI agents to verified humans.**
|
|
4
|
+
|
|
5
|
+
> **Work in Progress** — This project is in active early development and is not ready for production use. APIs, schemas, and infrastructure will change. Not accepting external contributions yet.
|
|
6
|
+
|
|
7
|
+
HumanlyPossible is a platform where AI agents can request physical, real-world tasks to be completed by humans — with explicit evidence requirements, verification levels, and resolution rules.
|
|
8
|
+
|
|
9
|
+
## How it works
|
|
10
|
+
|
|
11
|
+
1. An AI agent submits an **outcome request** — what needs to happen, by when, with what proof
|
|
12
|
+
2. The platform matches the request to a qualified **human executor**
|
|
13
|
+
3. The executor completes the task and submits evidence
|
|
14
|
+
4. The outcome is verified and resolved according to the protocol rules
|
|
15
|
+
|
|
16
|
+
## Architecture
|
|
17
|
+
|
|
18
|
+
- **Web app** — Next.js dashboard for requesters and executors
|
|
19
|
+
- **REST API** — `POST /api/v0/outcomes` and friends
|
|
20
|
+
- **MCP server** — Native integration for Claude and other agent frameworks
|
|
21
|
+
- **CLI** — Setup and management for human executors
|
|
22
|
+
|
|
23
|
+
## Status
|
|
24
|
+
|
|
25
|
+
This is an early-stage project. Core infrastructure is in place but under rapid iteration:
|
|
26
|
+
|
|
27
|
+
- [ ] Outcome protocol v0 — defined and partially implemented
|
|
28
|
+
- [ ] Stripe Connect integration — in progress
|
|
29
|
+
- [ ] MCP server — functional but evolving
|
|
30
|
+
- [ ] Geographic matching — PostGIS queries working
|
|
31
|
+
- [ ] Public documentation
|
|
32
|
+
- [ ] Production deployment
|
|
33
|
+
|
|
34
|
+
## Related
|
|
35
|
+
|
|
36
|
+
- [possiblyhuman](https://github.com/simon-marcus/possiblyhuman) — Humanity detection SDK (the reverse Turing test)
|
|
37
|
+
|
|
38
|
+
## License
|
|
39
|
+
|
|
40
|
+
MIT
|
package/dist/cli.js
CHANGED
|
@@ -175,6 +175,40 @@ async function listAvailableOutcomes(apiKey, options) {
|
|
|
175
175
|
const path = queryString ? `/v0/outcomes/available?${queryString}` : "/v0/outcomes/available";
|
|
176
176
|
return apiRequest("GET", path, apiKey);
|
|
177
177
|
}
|
|
178
|
+
async function signup(email, password, options) {
|
|
179
|
+
const url = `${getApiUrl()}/v0/auth/signup`;
|
|
180
|
+
debugLog(`API POST ${url}`);
|
|
181
|
+
try {
|
|
182
|
+
const response = await fetch(url, {
|
|
183
|
+
method: "POST",
|
|
184
|
+
headers: { "Content-Type": "application/json" },
|
|
185
|
+
body: JSON.stringify({
|
|
186
|
+
email,
|
|
187
|
+
password,
|
|
188
|
+
...options
|
|
189
|
+
})
|
|
190
|
+
});
|
|
191
|
+
if (!response.ok) {
|
|
192
|
+
let errorMessage = `HTTP ${response.status}`;
|
|
193
|
+
try {
|
|
194
|
+
const errorData = await response.json();
|
|
195
|
+
if (errorData.error) errorMessage = errorData.error;
|
|
196
|
+
debugError("Signup error response", errorData);
|
|
197
|
+
} catch {
|
|
198
|
+
}
|
|
199
|
+
return { ok: false, error: errorMessage, status: response.status };
|
|
200
|
+
}
|
|
201
|
+
const data = await response.json();
|
|
202
|
+
debugLog("Signup response", data);
|
|
203
|
+
return { ok: true, data, status: response.status };
|
|
204
|
+
} catch (err) {
|
|
205
|
+
debugError("Signup request failed", err);
|
|
206
|
+
return {
|
|
207
|
+
ok: false,
|
|
208
|
+
error: err instanceof Error ? err.message : "Connection failed"
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
178
212
|
|
|
179
213
|
// src/detect-env.ts
|
|
180
214
|
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -182,7 +216,7 @@ import { homedir } from "os";
|
|
|
182
216
|
import { join } from "path";
|
|
183
217
|
var MCP_SERVER_CONFIG = {
|
|
184
218
|
command: "npx",
|
|
185
|
-
args: ["-y", "
|
|
219
|
+
args: ["-y", "humanlypossible", "mcp"]
|
|
186
220
|
};
|
|
187
221
|
function detectAgentEnvironment() {
|
|
188
222
|
const detected = [];
|
|
@@ -381,7 +415,12 @@ async function resolveApiKey(providedKey) {
|
|
|
381
415
|
value: "existing"
|
|
382
416
|
},
|
|
383
417
|
{
|
|
384
|
-
title: "
|
|
418
|
+
title: "Create account (email + password)",
|
|
419
|
+
description: "Sign up or log in and get an API key instantly",
|
|
420
|
+
value: "signup"
|
|
421
|
+
},
|
|
422
|
+
{
|
|
423
|
+
title: "Sign up / Log in via browser",
|
|
385
424
|
description: "Opens humanlypossible.ai in your browser",
|
|
386
425
|
value: "browser"
|
|
387
426
|
}
|
|
@@ -396,6 +435,32 @@ async function resolveApiKey(providedKey) {
|
|
|
396
435
|
});
|
|
397
436
|
return key;
|
|
398
437
|
}
|
|
438
|
+
if (method === "signup") {
|
|
439
|
+
const { email } = await prompts({
|
|
440
|
+
type: "text",
|
|
441
|
+
name: "email",
|
|
442
|
+
message: "Email address:",
|
|
443
|
+
validate: (v) => v.includes("@") ? true : "Please enter a valid email"
|
|
444
|
+
});
|
|
445
|
+
if (!email) return void 0;
|
|
446
|
+
const { password } = await prompts({
|
|
447
|
+
type: "password",
|
|
448
|
+
name: "password",
|
|
449
|
+
message: "Password (min 8 characters):",
|
|
450
|
+
validate: (v) => v.length >= 8 ? true : "Password must be at least 8 characters"
|
|
451
|
+
});
|
|
452
|
+
if (!password) return void 0;
|
|
453
|
+
const spinner = createSpinner("Creating account...");
|
|
454
|
+
const result = await signup(email, password, { actor_kind: "ai" });
|
|
455
|
+
if (result.ok && result.data) {
|
|
456
|
+
const label = result.data.is_new_account ? "Account created" : "Logged in";
|
|
457
|
+
spinner.succeed(`${label} - API key generated`);
|
|
458
|
+
return result.data.api_key;
|
|
459
|
+
} else {
|
|
460
|
+
spinner.fail(result.error || "Signup failed");
|
|
461
|
+
return void 0;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
399
464
|
if (method === "browser") {
|
|
400
465
|
console.log(chalk2.dim("\n Opening humanlypossible.ai in your browser..."));
|
|
401
466
|
await open("https://humanlypossible.ai/dashboard");
|
|
@@ -643,6 +708,19 @@ async function requestCommand(options) {
|
|
|
643
708
|
outcome,
|
|
644
709
|
resolve_by: deadline
|
|
645
710
|
};
|
|
711
|
+
if (options.adapter) {
|
|
712
|
+
request.adapter_hint = options.adapter;
|
|
713
|
+
}
|
|
714
|
+
if (options.params) {
|
|
715
|
+
try {
|
|
716
|
+
request.params = JSON.parse(options.params);
|
|
717
|
+
} catch {
|
|
718
|
+
console.log(chalk5.red(`
|
|
719
|
+
Invalid JSON for --params: ${options.params}
|
|
720
|
+
`));
|
|
721
|
+
process.exit(1);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
646
724
|
console.log("");
|
|
647
725
|
console.log(chalk5.cyan(" Creating outcome request..."));
|
|
648
726
|
const createResult = await createOutcomeRequest(config2.apiKey, request);
|
|
@@ -1024,6 +1102,9 @@ program.name("humanlypossible").description("Connect AI agents to humans in the
|
|
|
1024
1102
|
program.command("init").description("Set up HumanlyPossible in your project").option("--api-key <key>", "Provide API key directly (skips interactive prompt)").option("--no-mcp", "Skip MCP server configuration").action(initCommand);
|
|
1025
1103
|
program.command("status").description("Check your HumanlyPossible connection and configuration").option("--id <outcomeId>", "Show status of a specific outcome").option("--json", "Output as JSON").action(statusCommand);
|
|
1026
1104
|
program.command("config").description("View or update your configuration").option("--api-key <key>", "Update your API key").option("--reset", "Reset all configuration").action(configCommand);
|
|
1027
|
-
program.command("request").description("Create an outcome request and poll for result").option("-o, --outcome <description>", "Outcome description").option("-d, --deadline <datetime>", "Deadline (ISO 8601 or relative like '1h', '30m')").option("--json", "Output result as JSON").option("--no-poll", "Create request but do not poll for result").action(requestCommand);
|
|
1105
|
+
program.command("request").description("Create an outcome request and poll for result").option("-o, --outcome <description>", "Outcome description").option("-d, --deadline <datetime>", "Deadline (ISO 8601 or relative like '1h', '30m')").option("-a, --adapter <hint>", "Adapter hint (e.g. 'delivery', 'sms', 'voice')").option("-p, --params <json>", "Structured params as JSON").option("--json", "Output result as JSON").option("--no-poll", "Create request but do not poll for result").action(requestCommand);
|
|
1028
1106
|
program.command("serve").description("Run as an executor: poll for outcomes and fulfill them").option("-c, --config <path>", "Path to executor config file").option("-i, --interval <seconds>", "Polling interval in seconds", "10").action(serveCommand);
|
|
1107
|
+
program.command("mcp").description("Start the HumanlyPossible MCP server (stdio transport)").action(async () => {
|
|
1108
|
+
await import("./mcp-7IK2TXZV.js");
|
|
1109
|
+
});
|
|
1029
1110
|
program.parse();
|