@sleep2agi/agent-network 2.3.0-preview.4 → 2.3.0-preview.41

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 (64) hide show
  1. package/README.md +35 -324
  2. package/dist/bin/anet.cjs +101 -0
  3. package/dist/bin/cli.d.ts +1 -0
  4. package/dist/bin/cli.js +20 -1
  5. package/dist/bin/goal-wake-log-render.d.ts +31 -0
  6. package/dist/src/batch-workdir.d.ts +9 -0
  7. package/dist/src/bootstrap-password-db.d.ts +13 -0
  8. package/dist/src/channel-attachments.d.ts +29 -0
  9. package/dist/src/channel-task-trace.d.ts +10 -0
  10. package/dist/src/claude-vendor-env.d.ts +28 -0
  11. package/dist/src/cli-args.d.ts +8 -0
  12. package/dist/src/client-task-trace.d.ts +9 -0
  13. package/dist/src/client.js +1 -1
  14. package/dist/src/codex-copresence-preflight.d.ts +65 -0
  15. package/dist/src/codex-copresence-profile.d.ts +68 -0
  16. package/dist/src/codex-model-default.d.ts +6 -0
  17. package/dist/src/controlled-upload.d.ts +83 -0
  18. package/dist/src/copresence-deps.d.ts +20 -0
  19. package/dist/src/copresence-identity.d.ts +339 -0
  20. package/dist/src/dashboard-managed-process.d.ts +35 -0
  21. package/dist/src/environ-alias.d.ts +14 -0
  22. package/dist/src/grok-attach-client.d.ts +115 -0
  23. package/dist/src/grok-copresence-disclosure.d.ts +11 -0
  24. package/dist/src/grok-copresence-profile.d.ts +65 -0
  25. package/dist/src/im/feishu/adapter.d.ts +149 -1
  26. package/dist/src/im/feishu/bridge.d.ts +9 -0
  27. package/dist/src/im/feishu/config.d.ts +31 -0
  28. package/dist/src/im/feishu/hub-upload.d.ts +88 -0
  29. package/dist/src/im/feishu/markdown-image-renderer.d.ts +61 -0
  30. package/dist/src/im/feishu/outbound-marker.d.ts +140 -0
  31. package/dist/src/im/feishu/outbound-paths.d.ts +50 -0
  32. package/dist/src/im/feishu/outbound-route.d.ts +62 -0
  33. package/dist/src/im/feishu/worker-lifecycle.d.ts +13 -0
  34. package/dist/src/im/feishu/worker.js +391 -16
  35. package/dist/src/im/types.d.ts +38 -1
  36. package/dist/src/locale-diagnostic.d.ts +12 -0
  37. package/dist/src/mock-llm.d.ts +12 -0
  38. package/dist/src/node-server.js +7 -1
  39. package/dist/src/normalize-runtime.d.ts +14 -2
  40. package/dist/src/opencode-agent-node-pair.d.ts +14 -0
  41. package/dist/src/opencode-auth-login.d.ts +43 -0
  42. package/dist/src/opencode-launch-env.d.ts +13 -0
  43. package/dist/src/opencode-owner-mode.d.ts +6 -0
  44. package/dist/src/opencode-package-binary.d.ts +21 -0
  45. package/dist/src/opencode-pin.d.ts +44 -0
  46. package/dist/src/opencode-preset.d.ts +73 -0
  47. package/dist/src/opencode-runtime-binding.d.ts +30 -0
  48. package/dist/src/opencode-safe-root.d.ts +27 -0
  49. package/dist/src/opencode-smoke-env.d.ts +1 -0
  50. package/dist/src/outbound-tool-names.d.ts +1 -0
  51. package/dist/src/owner-env-file.d.ts +2 -0
  52. package/dist/src/package-mode-preflight.d.ts +31 -0
  53. package/dist/src/primary-network.d.ts +23 -0
  54. package/dist/src/private-state.d.ts +10 -0
  55. package/dist/src/project-key.d.ts +1 -0
  56. package/dist/src/secret-shell-guidance.d.ts +3 -0
  57. package/dist/src/task-trace.d.ts +33 -0
  58. package/dist/src/tmux-attach.d.ts +8 -0
  59. package/dist/src/tmux-capability.d.ts +58 -0
  60. package/dist/src/tmux-exact-target.d.ts +34 -0
  61. package/dist/src/tmux-pane-prompt.d.ts +22 -0
  62. package/dist/src/token-cli.d.ts +13 -0
  63. package/dist/src/unsafe-package-path-reason.d.ts +17 -0
  64. package/package.json +10 -6
@@ -1,9 +1,21 @@
1
- export type RuntimeName = "claude-code-cli" | "codex-sdk" | "claude-agent-sdk" | "grok-build-acp";
2
- /** Operator-facing default for any runtime slot that comes in empty / missing / unrecognized. */
1
+ export type RuntimeName = "claude-code-cli" | "codex-sdk" | "claude-agent-sdk" | "grok-build-acp" | "grok-build-cli" | "opencode-cli" | "codex-app-server";
2
+ /** Operator-facing default for a runtime slot that is empty or missing. */
3
3
  export declare const DEFAULT_RUNTIME: RuntimeName;
4
+ export declare const SUPPORTED_RUNTIME_NAMES: readonly RuntimeName[];
4
5
  type ProfileLike = {
5
6
  runtime?: string;
6
7
  codexRuntime?: string;
7
8
  };
9
+ /**
10
+ * Legacy normalization used by display and migration code. Missing, empty,
11
+ * and unknown values all use the safe default for backward compatibility.
12
+ * Security-sensitive create/start paths must call `normalizeRuntimeStrict`.
13
+ */
8
14
  export declare function normalizeRuntime(profileOrRuntime?: ProfileLike | string): RuntimeName;
15
+ /**
16
+ * Canonicalize a runtime at an execution boundary. Missing/empty still means
17
+ * the documented default, but any non-empty unknown value is rejected so a
18
+ * typo or future runtime cannot silently execute as Claude.
19
+ */
20
+ export declare function normalizeRuntimeStrict(profileOrRuntime?: ProfileLike | string): RuntimeName;
9
21
  export {};
@@ -0,0 +1,14 @@
1
+ export declare const OPENCODE_AGENT_NETWORK_VERSION = "2.3.0-preview.41";
2
+ export declare const OPENCODE_AGENT_NODE_VERSION = "2.5.0-preview.32";
3
+ export declare const OPENCODE_AGENT_NODE_SPEC = "@sleep2agi/agent-node@2.5.0-preview.32";
4
+ export declare function opencodeExactPairInstallCommand(): string;
5
+ /** Runtime capability advertised by agent-node's operator-facing help. */
6
+ export declare function agentNodeHelpSupportsOpencode(help: string): boolean;
7
+ /**
8
+ * Resolve a package-owned agent-node entrypoint and verify its immutable
9
+ * release identity before it can receive `opencode-cli`. Capability text is
10
+ * not a security boundary: an older preview already advertised the runtime.
11
+ */
12
+ export declare function validateAgentNodePackageEntrypoint(rawEntrypoint: string, packageSpec: string, expectedVersion?: string, forbiddenRoots?: readonly string[]): string;
13
+ /** Skip invalid/local PATH shims and return the first exact trusted package. */
14
+ export declare function resolveAgentNodePackageEntrypointFromPath(searchPath: string, packageSpec: string, expectedVersion: string, forbiddenRoots?: readonly string[]): string;
@@ -0,0 +1,43 @@
1
+ import type { OpencodePresetId } from "./opencode-preset";
2
+ export declare const OPENCODE_AUTH_LOGIN_ROOT_PREFIX = "opencode-auth-login-";
3
+ export declare const OPENCODE_AUTH_LOGIN_OWNER_FILE = ".owner.json";
4
+ export declare const OPENCODE_AUTH_LOGIN_CLEANUP_PREFIX = ".anet-opencode-auth-cleanup-";
5
+ export interface OpencodeAuthLoginSandbox {
6
+ readonly nodeWorkDir: string;
7
+ readonly provider: OpencodePresetId;
8
+ readonly root: string;
9
+ readonly cwd: string;
10
+ readonly authPath: string;
11
+ readonly env: Readonly<NodeJS.ProcessEnv>;
12
+ }
13
+ export interface CreateOpencodeAuthLoginSandboxOptions {
14
+ nodeWorkDir: string;
15
+ provider: OpencodePresetId | string;
16
+ parentEnv?: NodeJS.ProcessEnv;
17
+ /** Internal/test-only trusted external base override. */
18
+ launchBase?: string;
19
+ }
20
+ export interface OpencodeAuthLoginCredential {
21
+ provider: OpencodePresetId;
22
+ type: "api";
23
+ key: string;
24
+ }
25
+ /** Deterministic exact-1.18.1 login argv for the selected API-key flow. */
26
+ export declare function buildOpencodeAuthLoginArgs(provider: OpencodePresetId | string): string[];
27
+ /** Prepare a fresh, node-scoped environment for one interactive login. */
28
+ export declare function createOpencodeAuthLoginSandbox(options: CreateOpencodeAuthLoginSandboxOptions): OpencodeAuthLoginSandbox;
29
+ /** Repeat external-root ancestor and inode validation immediately before the
30
+ * vetted upstream binary is spawned. */
31
+ export declare function revalidateOpencodeAuthLoginSandbox(sandbox: OpencodeAuthLoginSandbox): void;
32
+ /**
33
+ * Read only the selected provider's exact API-key shape from the fresh root.
34
+ * OAuth/browser-login records and mixed/multi-provider documents are refused.
35
+ */
36
+ export declare function readOpencodeAuthLoginCredential(sandbox: OpencodeAuthLoginSandbox): OpencodeAuthLoginCredential;
37
+ /** Safely remove a sandbox created by this process. Idempotent after removal. */
38
+ export declare function cleanupOpencodeAuthLoginSandbox(sandbox: OpencodeAuthLoginSandbox): void;
39
+ /**
40
+ * Lifecycle helper for CLI integration. Spawn/wait/read the credential inside
41
+ * `action`; the fresh tree is cleaned on success, child failure, or throw.
42
+ */
43
+ export declare function withOpencodeAuthLoginSandbox<T>(options: CreateOpencodeAuthLoginSandboxOptions, action: (sandbox: OpencodeAuthLoginSandbox) => T | Promise<T>): Promise<T>;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Process-loader hooks that must never cross the opencode-cli launcher
3
+ * boundary. The exact agent-node package/entrypoint check happens before the
4
+ * node profile env is merged; allowing that profile to supply one of these
5
+ * variables would let code run before the verified entrypoint's first line.
6
+ */
7
+ export declare const OPENCODE_AGENT_NODE_LOADER_ENV_KEYS: readonly ["NODE_OPTIONS", "NODE_PATH", "NODE_V8_COVERAGE", "NODE_REDIRECT_WARNINGS", "NODE_COMPILE_CACHE", "BUN_OPTIONS", "BUN_PRELOAD", "LD_PRELOAD", "LD_LIBRARY_PATH", "LD_AUDIT", "LD_DEBUG_OUTPUT", "DYLD_INSERT_LIBRARIES", "DYLD_LIBRARY_PATH", "DYLD_FRAMEWORK_PATH", "DYLD_FALLBACK_LIBRARY_PATH", "OPENSSL_CONF", "OPENSSL_ENGINES", "OPENSSL_MODULES"];
8
+ /**
9
+ * Return a child env that preserves the launcher's original executable search
10
+ * path and removes pre-entrypoint loader/write hooks. Other operator settings
11
+ * (locale, proxy, custom CA, channel integration) remain backward-compatible.
12
+ */
13
+ export declare function hardenOpencodeAgentNodeEnv(source: NodeJS.ProcessEnv, launcherPath: string | undefined): NodeJS.ProcessEnv;
@@ -0,0 +1,6 @@
1
+ /** Linux user-private-group compatibility for ordinary umask 0002 installs. */
2
+ export declare function opencodeOwnedPathModeIsSafe(stat: {
3
+ uid: number;
4
+ gid: number;
5
+ mode: number | bigint;
6
+ }, runtimeUid?: number | undefined, runtimeGid?: number | undefined): boolean;
@@ -0,0 +1,21 @@
1
+ export interface ValidateOpencodePackageBinaryOptions {
2
+ expectedVersion: string;
3
+ /** A package payload may not be inside, or contain, the current project or
4
+ * node state tree. This rejects project-local same-version impersonators. */
5
+ forbiddenRoots?: readonly string[];
6
+ }
7
+ /** Current cwd plus every enclosing source-workspace boundary. This catches a
8
+ * monorepo root's node_modules when anet is invoked from packages/app. */
9
+ export declare function discoverOpencodeForbiddenRoots(cwd?: string): string[];
10
+ /**
11
+ * Bind an executable to the exact npm `opencode-ai` payload identity.
12
+ *
13
+ * `--version` output alone is not an identity boundary: a checkout can put a
14
+ * same-version credential-stealing shim first on PATH. Only the canonical
15
+ * package entrypoint with matching package metadata and trusted path modes is
16
+ * admitted. The returned path is the one callers must spawn verbatim.
17
+ */
18
+ export declare function validateOpencodePackageBinary(rawBinary: string, options: ValidateOpencodePackageBinaryOptions): string;
19
+ /** Resolve the first *valid package-owned* OpenCode entry on PATH. Invalid
20
+ * project-local shims are skipped so a later trusted global install can win. */
21
+ export declare function resolveOpencodePackageBinaryFromPath(searchPath: string, options: ValidateOpencodePackageBinaryOptions): string;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Version this branch was validated against by the maintainers.
3
+ * Bumped when a new opencode-ai release passes the full Docker/E2E gate.
4
+ */
5
+ export declare const OPENCODE_BUILTIN_PIN = "1.18.1";
6
+ /** Exact upstream remediation shared by every CLI failure path. */
7
+ export declare function opencodeExactInstallCommand(version?: string): string;
8
+ /** Preserve package-identity diagnostics while always leaving a missing or
9
+ * untrusted install with an actionable exact-pin command. */
10
+ export declare function formatOpencodePackageIdentityFailure(expectedVersion: string, detail: string): string;
11
+ /** Where the per-machine override lives. Kept under `~/.anet/` so
12
+ * it sits next to the other anet-local state. */
13
+ export declare function opencodePinFilePath(homeDirOverride?: string): string;
14
+ /** Shape of the override file written by `upgrade-pin`. */
15
+ export interface OpencodePinOverride {
16
+ version: string;
17
+ /** ISO timestamp when the smoke test passed. Presence of this
18
+ * field is REQUIRED for `readEffectivePin()` to trust the file —
19
+ * a hand-edited version without a smoke marker is refused. */
20
+ smokePassedAt: string;
21
+ /** Free-form note about what the smoke checked (initialize +
22
+ * session/new by default). Kept so a future review can tell what
23
+ * bar the pin actually cleared. */
24
+ smokeNote?: string;
25
+ }
26
+ export interface EffectivePin {
27
+ version: string;
28
+ source: "override-file" | "builtin";
29
+ smokePassedAt?: string;
30
+ }
31
+ /**
32
+ * Recognize a validated override only when it records the exact built-in
33
+ * release pin. A different locally-smoked version is deliberately ignored:
34
+ * the lightweight ACP smoke does not replace the maintainer's full security
35
+ * and reply-path gate. Malformed/stale files also fall back to the built-in.
36
+ */
37
+ export declare function readEffectivePin(homeDirOverride?: string): EffectivePin;
38
+ /**
39
+ * Write the override — SHOULD ONLY be called after the smoke test
40
+ * has actually passed. The command layer in `bin/cli.ts` is
41
+ * responsible for gating this; this function does no
42
+ * verification of its own beyond shape.
43
+ */
44
+ export declare function writePinOverride(version: string, smokePassedAt: string, smokeNote?: string, homeDirOverride?: string): void;
@@ -0,0 +1,73 @@
1
+ export type OpencodePresetId = "anthropic" | "openai";
2
+ export interface OpencodePreset {
3
+ id: OpencodePresetId;
4
+ displayName: string;
5
+ envKey: string;
6
+ signupUrl: string;
7
+ /** How opencode's provider config identifies this vendor in the
8
+ * `provider.<id>.options.baseUrl` config. Left null when we don't
9
+ * need to override the built-in default. */
10
+ configProviderId: "anthropic" | "openai";
11
+ }
12
+ export declare const OPENCODE_PRESETS: OpencodePreset[];
13
+ /**
14
+ * OpenCode tools disabled for the default `opencode-cli` profile.
15
+ *
16
+ * This policy reduces the model's ambient filesystem/shell surface. It is
17
+ * deliberately represented in the generated opencode.json so operators can
18
+ * inspect the default, but it is not an OS security boundary: a same-uid
19
+ * OpenCode process can still read files allowed by normal filesystem ACLs.
20
+ */
21
+ export declare const OPENCODE_DEFAULT_DISABLED_TOOLS: readonly ["bash", "read", "glob", "grep", "edit", "write", "list", "task", "skill", "webfetch", "websearch", "question"];
22
+ export declare function buildOpencodeDefaultToolsPolicy(): Record<string, false>;
23
+ export declare function buildOpencodeDefaultPermissionPolicy(): Record<string, "deny">;
24
+ export declare function findOpencodePreset(id: string): OpencodePreset | null;
25
+ /**
26
+ * Look up the API key for a preset from the current process env.
27
+ * Callers MUST handle the `null` case (per RFC v0.3 D3 + 通信龙 PR③
28
+ * flag: "从 env 读, 别 prompt"). Returns null so the wizard can
29
+ * emit a clear message telling the operator to export the env var
30
+ * and re-run — rather than silently continuing without a key.
31
+ */
32
+ export declare function readPresetKeyFromEnv(preset: OpencodePreset, env?: NodeJS.ProcessEnv): string | null;
33
+ /**
34
+ * opencode.ai's auth.json shape:
35
+ * { "<providerId>": { "type": "api", "key": "..." } }
36
+ * Same shape verified against the release pin opencode-ai@1.18.1.
37
+ */
38
+ export declare function buildAuthJsonBody(preset: OpencodePreset, apiKey: string): string;
39
+ export type OpencodePrivateProfileFilename = "config.json" | ".env";
40
+ /**
41
+ * Establish the boundary before saveProfile/rewritePlainSecrets writes the
42
+ * node token or dotenv key. The expected shape is exactly
43
+ * `<project>/.anet/nodes/<node>`. Every existing path is inspected with
44
+ * lstat + O_NOFOLLOW and inode checks; absent private directories are created
45
+ * one component at a time. A pre-planted node-root/config/.env symlink is a
46
+ * hard error before any secret-bearing write.
47
+ */
48
+ export declare function prepareOpencodeNodeForProfileWrite(nodeWorkDir: string): string;
49
+ export declare function readOpencodePrivateProfileFile(nodeWorkDir: string, filename: OpencodePrivateProfileFilename): string | undefined;
50
+ export declare function writeOpencodePrivateProfileFile(nodeWorkDir: string, filename: OpencodePrivateProfileFilename, body: string): string;
51
+ /**
52
+ * Write auth.json into the opencode config root that lives under
53
+ * `nodeWorkDir` (the per-node OpenCode data root). mode 0o600 limits
54
+ * filesystem access to the owning OS account; it does not prevent a
55
+ * same-uid OpenCode child from opening the file directly. Directory is
56
+ * created if missing.
57
+ *
58
+ * Returns the absolute path we wrote for logging.
59
+ */
60
+ export declare function writeOpencodeAuthJson(nodeWorkDir: string, preset: OpencodePreset, apiKey: string): string;
61
+ /**
62
+ * New keyless nodes must not inherit a private-but-preplanted credential.
63
+ * Keep the file present as an explicit empty object so the creation log's
64
+ * "auth not configured" statement matches the state OpenCode will consume.
65
+ */
66
+ export declare function clearOpencodeAuthJson(nodeWorkDir: string): string;
67
+ /**
68
+ * Companion opencode.json: records only the selected blessed provider
69
+ * identity and safe-by-default tool policy. Pre-existing model routing and
70
+ * arbitrary OpenCode integrations are stripped; operators may explicitly set
71
+ * a model after creation, which the runtime's separate safe renderer retains.
72
+ */
73
+ export declare function writeOpencodeConfigJson(nodeWorkDir: string, preset: OpencodePreset): string;
@@ -0,0 +1,30 @@
1
+ export declare const OPENCODE_RUNTIME_BINDING_SCHEMA_VERSION: 1;
2
+ export declare const OPENCODE_RUNTIME_BINDING_RUNTIME: "opencode-cli";
3
+ export declare const OPENCODE_RUNTIME_BINDINGS_DIRECTORY = "opencode-runtime-bindings";
4
+ export interface OpencodeRuntimeBinding {
5
+ schemaVersion: typeof OPENCODE_RUNTIME_BINDING_SCHEMA_VERSION;
6
+ runtime: typeof OPENCODE_RUNTIME_BINDING_RUNTIME;
7
+ projectRoot: string;
8
+ nodeId: string;
9
+ }
10
+ /** Windows reports synthetic POSIX permission bits; retain all other checks there. */
11
+ export declare function isOpencodeRuntimeBindingModeSecure(mode: number, exactMode?: number, platform?: NodeJS.Platform): boolean;
12
+ /** Resolve the deterministic binding path without creating HOME state. */
13
+ export declare function opencodeRuntimeBindingPath(nodeWorkDir: string, homeDirectory?: string): string;
14
+ /** Persist an external, immutable-by-config record that this node was created as OpenCode. */
15
+ export declare function writeOpencodeRuntimeBinding(nodeWorkDir: string, homeDirectory?: string): string;
16
+ /** Read and validate a binding. Missing bindings return undefined; unsafe or tampered state throws. */
17
+ export declare function readOpencodeRuntimeBinding(nodeWorkDir: string, homeDirectory?: string): OpencodeRuntimeBinding | undefined;
18
+ /**
19
+ * Remove only the exact, validated binding for this node. Missing exact state is
20
+ * idempotent; malformed, replaced, or unsafe state always fails closed.
21
+ */
22
+ export declare function removeOpencodeRuntimeBinding(nodeWorkDir: string, homeDirectory?: string): boolean;
23
+ /** Assert that the external record exists and exactly identifies this node as opencode-cli. */
24
+ export declare function assertExactOpencodeRuntimeBinding(nodeWorkDir: string, homeDirectory?: string): OpencodeRuntimeBinding;
25
+ /**
26
+ * Refuse OpenCode node state committed to a surrounding Git index. A normal
27
+ * non-Git project is allowed. Git is always invoked directly with argv and a
28
+ * literal pathspec; no shell or command interpolation is used.
29
+ */
30
+ export declare function assertOpencodeNodeStateUntracked(nodeWorkDir: string): void;
@@ -0,0 +1,27 @@
1
+ /** Exact 1.18.1 project/instruction discovery surface plus project-root
2
+ * redirects. Any existing entry, including a broken symlink, is a refusal. */
3
+ export declare const OPENCODE_SAFE_ANCESTOR_CANDIDATES: readonly ["opencode.jsonc", "opencode.json", ".opencode", "AGENTS.md", "CLAUDE.md", "CONTEXT.md", ".claude", ".agents", ".git"];
4
+ interface PathIdentity {
5
+ path: string;
6
+ dev: number | bigint;
7
+ ino: number | bigint;
8
+ }
9
+ export interface OpencodeSafeExternalRoot {
10
+ readonly base: string;
11
+ readonly root: string;
12
+ readonly cwd: string;
13
+ readonly dev: number | bigint;
14
+ readonly ino: number | bigint;
15
+ readonly baseDev: number | bigint;
16
+ readonly baseIno: number | bigint;
17
+ readonly ancestors: readonly PathIdentity[];
18
+ }
19
+ export declare function resolveOpencodeTrustedRuntimeBase(explicit?: string): PathIdentity;
20
+ export declare function createOpencodeSafeExternalRoot(options: {
21
+ prefix: string;
22
+ boundaries?: readonly string[];
23
+ base?: string;
24
+ }): OpencodeSafeExternalRoot;
25
+ export declare function revalidateOpencodeSafeExternalRoot(context: OpencodeSafeExternalRoot): void;
26
+ export declare function cleanupOpencodeSafeExternalRoot(context: OpencodeSafeExternalRoot): void;
27
+ export {};
@@ -0,0 +1 @@
1
+ export declare function buildOpencodeSmokeEnv(parentEnv: NodeJS.ProcessEnv, smokeRoot: string, cwd?: string): NodeJS.ProcessEnv;
@@ -0,0 +1 @@
1
+ export declare const OUTBOUND_TOOL_NAMES: Set<string>;
@@ -0,0 +1,2 @@
1
+ /** Load a reviewed owner-only env file without following a planted link. */
2
+ export declare function loadOwnerOnlyEnvFile(path: string | undefined, env?: NodeJS.ProcessEnv): void;
@@ -0,0 +1,31 @@
1
+ export interface UmaskVerdict {
2
+ /** Will a freshly npm-extracted payload fail the (mode & 0o022) === 0 check? */
3
+ willProduceUnsafeModes: boolean;
4
+ /** Octal umask string as an operator would type it. */
5
+ umaskOctal: string;
6
+ /** Which write bits this umask fails to mask off. */
7
+ leaks: Array<"group" | "other">;
8
+ }
9
+ /**
10
+ * Read a umask value the way the package check will experience it.
11
+ *
12
+ * A umask bit SET means "withhold this permission". So group-write is withheld
13
+ * only when 0o020 is set in the umask; umask 0002 withholds other-write and
14
+ * nothing else, which is exactly the failing case.
15
+ */
16
+ export declare function judgeUmask(umask: number): UmaskVerdict;
17
+ /** One line for `anet doctor`, or null when there is nothing to say. */
18
+ export declare function describeUmaskRisk(verdict: UmaskVerdict): string | null;
19
+ export interface ExtractedPayload {
20
+ path: string;
21
+ uid: number;
22
+ mode: number;
23
+ }
24
+ /**
25
+ * Which already-extracted payloads would be rejected right now.
26
+ *
27
+ * Reports facts about copies that exist on disk; it never fetches. An empty
28
+ * result means "nothing extracted yet", which is not the same as "safe" — the
29
+ * umask verdict is what speaks to the next fetch.
30
+ */
31
+ export declare function rejectedPayloads(payloads: ExtractedPayload[], processUid: number): ExtractedPayload[];
@@ -0,0 +1,23 @@
1
+ export interface PrimaryNetworkResponse {
2
+ ok?: boolean;
3
+ current_network?: unknown;
4
+ networks?: unknown;
5
+ }
6
+ export type PrimaryNetworkFetch = (input: string, init: {
7
+ headers: Record<string, string>;
8
+ }) => Promise<{
9
+ ok: boolean;
10
+ status: number;
11
+ json: () => Promise<PrimaryNetworkResponse>;
12
+ }>;
13
+ export declare class PrimaryNetworkResolutionError extends Error {
14
+ constructor(message: string, options?: ErrorOptions);
15
+ }
16
+ /**
17
+ * Resolve the authenticated user's active network from the server's explicit
18
+ * `/api/auth/me.current_network` field.
19
+ *
20
+ * Do not fall back to a network name or list position: both are presentation
21
+ * details, and guessing either can silently run a command in the wrong network.
22
+ */
23
+ export declare function resolvePrimaryNetwork(hub: string, headers: Record<string, string>, fetchImpl?: PrimaryNetworkFetch): Promise<string>;
@@ -0,0 +1,10 @@
1
+ export declare function ensurePrivateDirectory(path: string): void;
2
+ /**
3
+ * Write secret-bearing state without ever publishing an umask-derived file.
4
+ * The 0600 temporary file is complete and fsynced before the atomic rename,
5
+ * so replacing a legacy 0644/0664 target also repairs it with no chmod gap.
6
+ */
7
+ export declare function atomicWritePrivateFile(path: string, body: string): void;
8
+ export declare function atomicWritePrivateJson(path: string, value: unknown): void;
9
+ /** Repair a legacy umask-derived private file before reading its secret. */
10
+ export declare function repairPrivateFilePermissions(path: string): void;
@@ -0,0 +1 @@
1
+ export declare function encodeCwd(cwd: string): string;
@@ -0,0 +1,3 @@
1
+ export declare function formatSecretAssignment(platform: string, name: string, value: string): string;
2
+ export declare function secretPersistenceHeading(platform: string): string;
3
+ export declare function secretShellAction(platform: string): "set" | "export";
@@ -0,0 +1,33 @@
1
+ export type TaskTraceTransport = "mcp_http" | "sdk_mcp_proxy" | "channel_mcp_proxy";
2
+ export type TaskTraceStatus = "sending" | "delivered" | "failed" | "acked" | "started" | "replied" | "expired";
3
+ export interface TaskTraceEvent {
4
+ event: string;
5
+ from_alias: string;
6
+ to_alias: string;
7
+ task_id: string | null;
8
+ parent_task_id: string | null;
9
+ network_id: string | null;
10
+ transport: TaskTraceTransport;
11
+ status: TaskTraceStatus;
12
+ duration_ms: number;
13
+ lifecycle_tracking: "tracked" | "not_tracked";
14
+ error_code?: string;
15
+ error_message?: string;
16
+ }
17
+ export declare function safeTaskTraceError(value: unknown): string;
18
+ export declare function renderTaskTrace(event: TaskTraceEvent, json?: boolean): string;
19
+ export declare function taskTraceEvent(input: Omit<TaskTraceEvent, "event">): TaskTraceEvent;
20
+ export interface SendTaskTraceInput {
21
+ fromAlias: string;
22
+ toAlias: string;
23
+ parentTaskId: string | null;
24
+ networkId: string | null;
25
+ transport: TaskTraceTransport;
26
+ lifecycleTracking: "tracked" | "not_tracked";
27
+ }
28
+ export interface SendTaskTraceDependencies {
29
+ send: () => Promise<any>;
30
+ log: (line: string) => void;
31
+ now?: () => number;
32
+ }
33
+ export declare function sendTaskWithTrace(input: SendTaskTraceInput, dependencies: SendTaskTraceDependencies): Promise<any>;
@@ -0,0 +1,8 @@
1
+ export type TmuxSession = {
2
+ id: string;
3
+ name: string;
4
+ };
5
+ export declare function parseTmuxSessions(output: string): TmuxSession[];
6
+ /** Resolve by exact decoded session name, then attach by tmux's opaque ID.
7
+ * This avoids tmux target prefix matching and works for Unicode names. */
8
+ export declare function findExactTmuxSession(output: string, expectedName: string): TmuxSession | null;
@@ -0,0 +1,58 @@
1
+ /** Lowest tmux version whose `new-session` understands `-e KEY=VALUE`. */
2
+ export declare const MIN_TMUX_MAJOR = 3;
3
+ export declare const MIN_TMUX_MINOR = 2;
4
+ export interface TmuxVersion {
5
+ major: number;
6
+ minor: number;
7
+ /** Trailing letter suffix, e.g. the "a" of "3.0a". Not used for ordering. */
8
+ suffix: string;
9
+ raw: string;
10
+ }
11
+ /**
12
+ * Parse the output of `tmux -V`, e.g.:
13
+ * "tmux 3.2a" → { major: 3, minor: 2, suffix: "a" }
14
+ * "tmux 3.0a" → { major: 3, minor: 0, suffix: "a" }
15
+ * "tmux 3.4" → { major: 3, minor: 4, suffix: "" }
16
+ * "tmux next-3.4" → { major: 3, minor: 4, suffix: "" }
17
+ * "tmux 2.9" → { major: 2, minor: 9, suffix: "" }
18
+ *
19
+ * Returns null when no version can be extracted (unknown build, empty
20
+ * output, `tmux master` with no numbers). Callers must treat null as
21
+ * "unknown" and NOT as "too old" — refusing to start on an unparseable
22
+ * version string would break hosts whose tmux is perfectly capable.
23
+ */
24
+ export declare function parseTmuxVersion(raw: string): TmuxVersion | null;
25
+ /**
26
+ * True when this version's `new-session` supports `-e KEY=VALUE` (>= 3.2).
27
+ * Note 3.0a / 3.1c sort BELOW 3.2 — the letter suffix is a patch marker,
28
+ * never a minor bump, so it must not participate in the comparison.
29
+ */
30
+ export declare function tmuxSupportsSessionEnv(v: TmuxVersion): boolean;
31
+ export type TmuxCapabilityVerdict = {
32
+ kind: "ok";
33
+ version: TmuxVersion;
34
+ } | {
35
+ kind: "unknown";
36
+ detail: string;
37
+ } | {
38
+ kind: "too_old";
39
+ version: TmuxVersion;
40
+ detail: string;
41
+ remedy: string[];
42
+ } | {
43
+ kind: "missing";
44
+ detail: string;
45
+ remedy: string[];
46
+ };
47
+ /**
48
+ * Pure decision function — `runVersionCmd` returns `tmux -V` output, or
49
+ * throws if tmux is absent/unrunnable. Split from the printing/exiting
50
+ * wrapper so tests drive every branch without a tmux binary.
51
+ */
52
+ export declare function checkTmuxCapability(runVersionCmd: () => string): TmuxCapabilityVerdict;
53
+ /**
54
+ * cli.ts wrapper: run the check, print an actionable message, and exit
55
+ * non-zero when tmux cannot carry the marker. `unknown` is deliberately
56
+ * permissive — we log and continue.
57
+ */
58
+ export declare function assertTmuxSupportsSessionEnv(runVersionCmd: () => string, log: (msg: string) => void, fail: (msg: string) => never): void;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Exact-match tmux target for a session name.
3
+ *
4
+ * tmux treats a leading `=` as "this exact name, no prefix matching". Names are
5
+ * passed to tmux as argv entries, never through a shell, so no quoting belongs
6
+ * here — callers that build a copy-pasteable command for a human should shell-
7
+ * quote the result themselves.
8
+ */
9
+ export declare function exactSession(name: string): string;
10
+ /**
11
+ * True when this target is already pinned to an exact session.
12
+ *
13
+ * Applying the prefix twice would look for a session literally named `=x`.
14
+ */
15
+ export declare function isExactTarget(target: string): boolean;
16
+ /** Idempotent form, for call sites that may receive either shape. */
17
+ export declare function ensureExactSession(nameOrTarget: string): string;
18
+ /** One row of `tmux list-panes -a -F '#{session_name}\t#{window_index}.#{pane_index}'`. */
19
+ export interface PaneRow {
20
+ session: string;
21
+ /** `window.pane`, e.g. `0.0`. */
22
+ coord: string;
23
+ }
24
+ export declare function parsePaneRows(listOutput: string): PaneRow[];
25
+ /**
26
+ * Pane target for a session, or null when that exact session has no pane.
27
+ *
28
+ * Matching is exact string equality on the session name — the whole point is to
29
+ * not hand tmux a name it might prefix-match, and to not hand it a `=` form it
30
+ * cannot resolve for non-ASCII names.
31
+ */
32
+ export declare function paneTargetFor(listOutput: string, sessionName: string): string | null;
33
+ /** The format string the two functions above expect. */
34
+ export declare const PANE_LIST_FORMAT = "#{session_name}\t#{window_index}.#{pane_index}";
@@ -0,0 +1,22 @@
1
+ /** A prompt the watcher knows how to answer, or null. */
2
+ export type PanePrompt = "dev-channels" | "folder-trust";
3
+ /**
4
+ * Which known prompt (if any) the pane is currently blocking on.
5
+ *
6
+ * Dev-channels is checked FIRST, even though it appears second in time. The two
7
+ * prompts are sequential — trust, then channels — so a capture showing both
8
+ * means the trust prompt is already answered and only its text is still sitting
9
+ * in the pane. Classifying that as "folder-trust" would make a watcher that has
10
+ * already answered trust ignore the prompt it was waiting for, and the node
11
+ * would hang exactly as if the fix had never been made. Preferring the later
12
+ * prompt keeps a stale line of scrollback from outranking the live prompt.
13
+ */
14
+ export declare function classifyPanePrompt(pane: string): PanePrompt | null;
15
+ /**
16
+ * Best-effort one-line explanation of why a detached start died, taken from the
17
+ * dead pane's own output.
18
+ *
19
+ * Returns null when the pane holds nothing that looks like a refusal — the
20
+ * caller must then fall back to a generic message rather than inventing one.
21
+ */
22
+ export declare function extractStartFailureReason(pane: string): string | null;
@@ -0,0 +1,13 @@
1
+ export type TokenCreateNameResult = {
2
+ ok: true;
3
+ name: string;
4
+ } | {
5
+ ok: false;
6
+ error: string;
7
+ };
8
+ /** Parse only `anet token create` operands.
9
+ *
10
+ * The legacy positional form stays supported, while flag parsing is strict so
11
+ * a typo cannot become the name of a newly issued credential.
12
+ */
13
+ export declare function parseTokenCreateName(argv: readonly string[]): TokenCreateNameResult;
@@ -0,0 +1,17 @@
1
+ export interface PathModeFacts {
2
+ /** Owner uid of the path. */
3
+ uid: number;
4
+ /** Permission bits (st_mode & 0o777). */
5
+ mode: number;
6
+ /** uid of the process doing the check. */
7
+ processUid: number;
8
+ }
9
+ export type UnsafePathReason = "owner" | "group-writable" | "world-writable" | null;
10
+ /** Which condition makes this path unsafe to execute from, if any. */
11
+ export declare function classifyUnsafePath(facts: PathModeFacts): UnsafePathReason;
12
+ /**
13
+ * Operator-facing explanation. Names the path, the offending bits, and the
14
+ * command that fixes it — a message that says only "unsafe" leaves the reader
15
+ * guessing between four different conditions.
16
+ */
17
+ export declare function describeUnsafePath(path: string, facts: PathModeFacts): string;