humanish 0.95.0 → 0.96.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 +4 -2
- package/dist/comms-agentmail.d.ts +25 -0
- package/dist/comms-agentmail.js +418 -0
- package/dist/comms-agentmail.js.map +1 -0
- package/dist/comms-connections.d.ts +4 -2
- package/dist/comms-connections.js +3 -3
- package/dist/comms-connections.js.map +1 -1
- package/dist/comms-lease-store.d.ts +90 -0
- package/dist/comms-lease-store.js +489 -0
- package/dist/comms-lease-store.js.map +1 -0
- package/dist/comms-receiving-evidence.d.ts +46 -0
- package/dist/comms-receiving-evidence.js +35 -0
- package/dist/comms-receiving-evidence.js.map +1 -0
- package/dist/comms-receiving-inbox.d.ts +16 -0
- package/dist/comms-receiving-inbox.js +410 -0
- package/dist/comms-receiving-inbox.js.map +1 -0
- package/dist/comms-receiving-runtime.d.ts +25 -0
- package/dist/comms-receiving-runtime.js +45 -0
- package/dist/comms-receiving-runtime.js.map +1 -0
- package/dist/comms-receiving-types.d.ts +98 -0
- package/dist/comms-receiving-types.js +2 -0
- package/dist/comms-receiving-types.js.map +1 -0
- package/dist/comms-receiving.d.ts +58 -0
- package/dist/comms-receiving.js +554 -0
- package/dist/comms-receiving.js.map +1 -0
- package/dist/comms-setup.d.ts +40 -0
- package/dist/comms-setup.js +121 -0
- package/dist/comms-setup.js.map +1 -0
- package/dist/concurrent-shared-world-lab.js +662 -624
- package/dist/concurrent-shared-world-lab.js.map +1 -1
- package/dist/cua-actor-lab.d.ts +4 -1
- package/dist/cua-actor-lab.js +98 -17
- package/dist/cua-actor-lab.js.map +1 -1
- package/dist/doctor-lab.js +11 -0
- package/dist/doctor-lab.js.map +1 -1
- package/dist/e2b-terminal-lab.js +3 -0
- package/dist/e2b-terminal-lab.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lab-config.d.ts +20 -3
- package/dist/lab-config.js +59 -6
- package/dist/lab-config.js.map +1 -1
- package/dist/lab-engine.js +8 -3
- package/dist/lab-engine.js.map +1 -1
- package/dist/lab-summary.d.ts +1 -0
- package/dist/lab-summary.js +8 -2
- package/dist/lab-summary.js.map +1 -1
- package/dist/observer-app.html +1 -1
- package/dist/observer-data.js +14 -1
- package/dist/observer-data.js.map +1 -1
- package/dist/oss-lab.d.ts +1 -1
- package/dist/oss-lab.js.map +1 -1
- package/dist/oss-meta-lab.d.ts +1 -1
- package/dist/oss-meta-lab.js.map +1 -1
- package/dist/program.d.ts +2 -0
- package/dist/program.js +100 -4
- package/dist/program.js.map +1 -1
- package/dist/run-narration-secrets.d.ts +5 -0
- package/dist/run-narration-secrets.js +68 -0
- package/dist/run-narration-secrets.js.map +1 -0
- package/dist/run.d.ts +7 -2
- package/dist/run.js +25 -3
- package/dist/run.js.map +1 -1
- package/dist/scripted-browser-lab.js +7 -0
- package/dist/scripted-browser-lab.js.map +1 -1
- package/dist/shared-world-lab.js +4 -0
- package/dist/shared-world-lab.js.map +1 -1
- package/dist/study-analysis-engine.js +30 -1
- package/dist/study-analysis-engine.js.map +1 -1
- package/dist/study-analysis-evidence.js +9 -1
- package/dist/study-analysis-evidence.js.map +1 -1
- package/dist/tui-app.js +134 -134
- package/dist/tui-contract.d.ts +13 -0
- package/dist/tui-contract.js.map +1 -1
- package/dist/tui-launch.d.ts +2 -0
- package/dist/tui-launch.js +9 -1
- package/dist/tui-launch.js.map +1 -1
- package/docs/architecture/comms-inbox.md +4 -0
- package/docs/architecture/real-email-receiving.md +135 -0
- package/docs/contracts/run-bundle.md +9 -1
- package/docs/contracts/schemas.md +20 -3
- package/docs/goals/current.md +5 -5
- package/docs/ramp/README.md +9 -5
- package/docs/release/0.96.0-real-email-receiving.md +47 -0
- package/package.json +2 -1
- package/skills/humanish/SKILL.md +33 -13
package/dist/program.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type AutomaticAnalysisHooks } from "./automatic-analysis-completion.js";
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import { discoverProviderKeys } from "./key-resolution.js";
|
|
4
|
+
import { checkCommsConnection } from "./comms-setup.js";
|
|
4
5
|
import { promptSecret } from "./secret-prompt.js";
|
|
5
6
|
import { type TelemetryProperties } from "./telemetry.js";
|
|
6
7
|
import type { CuaActorLabResult } from "./cua-actor-lab.js";
|
|
@@ -40,6 +41,7 @@ export declare function createProgram(io?: Partial<CliIo> & {
|
|
|
40
41
|
* TTY, an old Node, or a missing bundle appear.
|
|
41
42
|
*/
|
|
42
43
|
export interface TuiRuntime {
|
|
44
|
+
checkComms: typeof checkCommsConnection;
|
|
43
45
|
promptSecret: typeof promptSecret;
|
|
44
46
|
stdin: NodeJS.ReadStream;
|
|
45
47
|
stdout: NodeJS.WriteStream;
|
package/dist/program.js
CHANGED
|
@@ -11,6 +11,9 @@ import { startCodexAppServerUi } from "./codex-app-server-ui.js";
|
|
|
11
11
|
import { loadEnvFile } from "./env-file.js";
|
|
12
12
|
import { discoverProviderKeys, listUserKeys, resolveKeyName, setUserKey, unsetUserKey, userKeyStorePath } from "./key-resolution.js";
|
|
13
13
|
import { COMMS_PROVIDERS, readCommsSetup, saveCommsConnection } from "./comms-connections.js";
|
|
14
|
+
import { checkCommsConnection, configureCommsLab } from "./comms-setup.js";
|
|
15
|
+
import { inspectCommsRecovery, recoverCommsReceiving } from "./comms-receiving.js";
|
|
16
|
+
import { resolveReceivingConnection } from "./comms-receiving-runtime.js";
|
|
14
17
|
import { promptSecret } from "./secret-prompt.js";
|
|
15
18
|
import { redactText } from "./redaction.js";
|
|
16
19
|
import { draftFeedback, listFeedback, renderIssueMarkdown, renderIssueUrl, verifyFeedback } from "./feedback.js";
|
|
@@ -463,6 +466,7 @@ function registerDoctorCommand(parent, io) {
|
|
|
463
466
|
});
|
|
464
467
|
}
|
|
465
468
|
const defaultTuiRuntime = {
|
|
469
|
+
checkComms: checkCommsConnection,
|
|
466
470
|
promptSecret,
|
|
467
471
|
stdin: process.stdin,
|
|
468
472
|
stdout: process.stdout,
|
|
@@ -645,6 +649,7 @@ function registerTuiCommand(parent, io) {
|
|
|
645
649
|
const observerSession = createTuiObserverSession(resolve(options.cwd));
|
|
646
650
|
let exitCode = 0;
|
|
647
651
|
let connectionNotice;
|
|
652
|
+
let connectionCheck;
|
|
648
653
|
try {
|
|
649
654
|
for (;;) {
|
|
650
655
|
const outcome = await loaded.startTui({
|
|
@@ -653,8 +658,21 @@ function registerTuiCommand(parent, io) {
|
|
|
653
658
|
version: { cli: CLI_VERSION },
|
|
654
659
|
capabilities: {
|
|
655
660
|
comms: {
|
|
656
|
-
read: () => readCommsSetup(resolve(options.cwd), connectionEnv()),
|
|
657
|
-
save: () => saveCommsConnection(resolve(options.cwd))
|
|
661
|
+
read: async () => ({ ...await readCommsSetup(resolve(options.cwd), connectionEnv()), ...(connectionCheck ? { authentication: connectionCheck } : {}) }),
|
|
662
|
+
save: () => saveCommsConnection(resolve(options.cwd)),
|
|
663
|
+
check: async () => { connectionCheck = await tuiRuntime.checkComms({ cwd: resolve(options.cwd), env: connectionEnv(), online: true }); return connectionCheck; },
|
|
664
|
+
labs: async () => (await listLabManifests(resolve(options.cwd))).labs.map(lab => ({ title: lab.title ?? lab.id, path: lab.path })),
|
|
665
|
+
configure: (lab, apply, planToken) => configureCommsLab({ cwd: resolve(options.cwd), lab, connection: "agentmail", apply, ...(planToken ? { planToken } : {}) }),
|
|
666
|
+
recovery: () => inspectCommsRecovery({ cwd: resolve(options.cwd) }),
|
|
667
|
+
recover: async (runId, connectionName) => {
|
|
668
|
+
try {
|
|
669
|
+
const { connection, adapter } = await resolveReceivingConnection(resolve(options.cwd), connectionName, connectionEnv());
|
|
670
|
+
return await recoverCommsReceiving({ cwd: resolve(options.cwd), runId, connectionName, apiKeyEnv: connection.apiKeyEnv, adapter });
|
|
671
|
+
}
|
|
672
|
+
catch {
|
|
673
|
+
return { ok: false, message: "Could not recover email resources. Check the connection and retry." };
|
|
674
|
+
}
|
|
675
|
+
}
|
|
658
676
|
},
|
|
659
677
|
// One cache for the life of the surface: it refreshes on a cadence, and re-walking every
|
|
660
678
|
// run tree each tick is the cost this index exists to avoid.
|
|
@@ -708,6 +726,13 @@ function registerTuiCommand(parent, io) {
|
|
|
708
726
|
const saved = await saveCommsConnection(resolve(options.cwd));
|
|
709
727
|
connectionNotice = saved.ok ? "Key stored. Project connection saved."
|
|
710
728
|
: `Key stored for your user. ${saved.message}`;
|
|
729
|
+
stdout.write("Checking AgentMail authentication…\n");
|
|
730
|
+
connectionCheck = await tuiRuntime.checkComms({ cwd: resolve(options.cwd), env: connectionEnv(), online: true });
|
|
731
|
+
connectionNotice = saved.ok
|
|
732
|
+
? connectionCheck.authenticated === true ? "Key stored. Authentication passed."
|
|
733
|
+
: connectionCheck.authenticated === false ? "Key stored. Authentication rejected; test it for details."
|
|
734
|
+
: "Key stored. Authentication unknown; test it to retry."
|
|
735
|
+
: `${connectionNotice} ${connectionCheck.message}`;
|
|
711
736
|
}
|
|
712
737
|
catch {
|
|
713
738
|
connectionNotice = "Could not store the key. Use a single non-empty line and check key-store permissions.";
|
|
@@ -1162,7 +1187,7 @@ function registerRunsCommand(parent, io) {
|
|
|
1162
1187
|
function registerCommsCommands(parent, io) {
|
|
1163
1188
|
const comms = parent
|
|
1164
1189
|
.command("comms")
|
|
1165
|
-
.description("
|
|
1190
|
+
.description("Local email capture, real receiving connections, checks and cleanup recovery.")
|
|
1166
1191
|
.summary("Off-app comms surfaces.");
|
|
1167
1192
|
comms.command("providers")
|
|
1168
1193
|
.description("List installed communication provider capabilities. No network requests.")
|
|
@@ -1171,7 +1196,7 @@ function registerCommsCommands(parent, io) {
|
|
|
1171
1196
|
const result = { schema: "humanish.comms-providers.v1", ok: true, providers: COMMS_PROVIDERS };
|
|
1172
1197
|
writeResult(command, io, result, () => COMMS_PROVIDERS.map(provider => `${provider.label}: ${provider.limitation}\nKey: ${provider.keyEnv}\nSetup: ${provider.setupUrl}\n`).join("\n"));
|
|
1173
1198
|
});
|
|
1174
|
-
const connections = comms.command("connections").description("Manage project-local non-secret connection profiles.
|
|
1199
|
+
const connections = comms.command("connections").description("Manage project-local non-secret connection profiles. A lab explicitly selects its receiving connection.");
|
|
1175
1200
|
connections.command("list")
|
|
1176
1201
|
.description("Show saved connections and local credential status; does not authenticate with a provider.")
|
|
1177
1202
|
.option("--cwd <path>", "Target project directory.", ".")
|
|
@@ -1198,6 +1223,77 @@ function registerCommsCommands(parent, io) {
|
|
|
1198
1223
|
writeResult(command, io, result, value => `${value.message}\n`);
|
|
1199
1224
|
io.setExitCode(result.ok ? 0 : 2);
|
|
1200
1225
|
});
|
|
1226
|
+
comms.command("check")
|
|
1227
|
+
.description("Check connection and credential presence; --online authenticates without creating inboxes.")
|
|
1228
|
+
.option("--cwd <path>", "Target project directory.", ".")
|
|
1229
|
+
.option("--connection <name>", "Saved connection name.", "agentmail")
|
|
1230
|
+
.option("--lab <path>", "Check the connection selected by this exact lab.")
|
|
1231
|
+
.option("--online", "Make a read-only provider authentication request.")
|
|
1232
|
+
.option("--env-file <path>", "Load credentials without printing values.")
|
|
1233
|
+
.option("--json", JSON_OPTION_DESCRIPTION)
|
|
1234
|
+
.action(async (options, command) => {
|
|
1235
|
+
if (!await applyEnvFileOption({ command, cwd: options.cwd, envFile: options.envFile, io }))
|
|
1236
|
+
return;
|
|
1237
|
+
let connection = options.connection;
|
|
1238
|
+
if (options.lab) {
|
|
1239
|
+
const lab = await resolveLabManifest(options.cwd, options.lab);
|
|
1240
|
+
if (!lab.ok || lab.config.comms?.email?.kind !== "real") {
|
|
1241
|
+
const result = { ok: false, message: "This lab does not select a real email connection." };
|
|
1242
|
+
writeResult(command, io, result, value => `${value.message}\n`);
|
|
1243
|
+
io.setExitCode(2);
|
|
1244
|
+
return;
|
|
1245
|
+
}
|
|
1246
|
+
connection = lab.config.comms.email.connection;
|
|
1247
|
+
}
|
|
1248
|
+
const result = await checkCommsConnection({ cwd: resolve(options.cwd), connection, env: process.env, online: options.online === true });
|
|
1249
|
+
writeResult(command, io, result, value => `${value.message}\n`);
|
|
1250
|
+
io.setExitCode(result.ok ? 0 : 2);
|
|
1251
|
+
});
|
|
1252
|
+
comms.command("configure")
|
|
1253
|
+
.description("Preview or save a local receiving-enabled copy of a supported lab. No provider requests.")
|
|
1254
|
+
.requiredOption("--lab <path>", "Exact source lab path or handle.")
|
|
1255
|
+
.option("--cwd <path>", "Target project directory.", ".")
|
|
1256
|
+
.option("--connection <name>", "Saved connection name.", "agentmail")
|
|
1257
|
+
.option("--apply", "Save the local copy; original lab remains unchanged.")
|
|
1258
|
+
.option("--plan-token <digest>", "Require the source and destination to match a previous preview.")
|
|
1259
|
+
.option("--json", JSON_OPTION_DESCRIPTION)
|
|
1260
|
+
.action(async (options, command) => {
|
|
1261
|
+
const result = await configureCommsLab({ ...options, cwd: resolve(options.cwd) });
|
|
1262
|
+
writeResult(command, io, result, value => `${value.message}\n`);
|
|
1263
|
+
io.setExitCode(result.ok ? 0 : 2);
|
|
1264
|
+
});
|
|
1265
|
+
comms.command("recover")
|
|
1266
|
+
.description("Inspect interrupted email leases; --apply deletes only privately recorded resources owned by this project and account.")
|
|
1267
|
+
.option("--cwd <path>", "Target project directory.", ".")
|
|
1268
|
+
.option("--run <id>", "One run to inspect or recover.")
|
|
1269
|
+
.option("--apply", "Recover the selected inactive run and verify mailbox deletion.")
|
|
1270
|
+
.option("--env-file <path>", "Load credentials without printing values.")
|
|
1271
|
+
.option("--json", JSON_OPTION_DESCRIPTION)
|
|
1272
|
+
.action(async (options, command) => {
|
|
1273
|
+
if (!await applyEnvFileOption({ command, cwd: options.cwd, envFile: options.envFile, io }))
|
|
1274
|
+
return;
|
|
1275
|
+
const cwd = resolve(options.cwd);
|
|
1276
|
+
try {
|
|
1277
|
+
const entries = (await inspectCommsRecovery({ cwd })).filter(entry => !options.run || entry.runId === options.run);
|
|
1278
|
+
if (!options.apply) {
|
|
1279
|
+
const result = { schema: "humanish.comms-recovery.v1", ok: true, entries };
|
|
1280
|
+
writeResult(command, io, result, value => value.entries.length ? value.entries.map(entry => `${entry.runId}: ${entry.unresolvedCount} unresolved; ${entry.activeOwner === null ? "unknown owner" : entry.activeOwner ? "active owner" : "inactive"}\n`).join("") : "No recoverable email leases in this project.\n");
|
|
1281
|
+
return;
|
|
1282
|
+
}
|
|
1283
|
+
if (!options.run || entries.length !== 1)
|
|
1284
|
+
throw new Error("selection");
|
|
1285
|
+
const entry = entries[0];
|
|
1286
|
+
const { connection, adapter } = await resolveReceivingConnection(cwd, entry.connectionName, process.env);
|
|
1287
|
+
const result = { schema: "humanish.comms-recovery-result.v1", ...await recoverCommsReceiving({ cwd, runId: options.run, connectionName: entry.connectionName, apiKeyEnv: connection.apiKeyEnv, adapter }) };
|
|
1288
|
+
writeResult(command, io, result, value => `${value.message}\n`);
|
|
1289
|
+
io.setExitCode(result.ok ? 0 : 2);
|
|
1290
|
+
}
|
|
1291
|
+
catch {
|
|
1292
|
+
const result = { schema: "humanish.comms-recovery-result.v1", ok: false, message: "Recovery could not complete. Select one recorded run with --run, check its connection, and retry. No unrecorded resources are eligible." };
|
|
1293
|
+
writeResult(command, io, result, value => `${value.message}\n`);
|
|
1294
|
+
io.setExitCode(2);
|
|
1295
|
+
}
|
|
1296
|
+
});
|
|
1201
1297
|
comms
|
|
1202
1298
|
.command("catch")
|
|
1203
1299
|
.description("Run the email catch on THIS host so humanish can study an app it does not provision (#328). Your app posts its email sends here; the persona opens /inbox; humanish drains GET /deliveries and writes digest-only evidence. Point your lab's comms.email.external.catchBaseUrl at this server.")
|