@abaigram/abai-stub 0.0.0-stage → 0.1.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.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +22 -2
  3. package/dist/audit.d.ts +70 -0
  4. package/dist/audit.d.ts.map +1 -0
  5. package/dist/audit.js +166 -0
  6. package/dist/audit.js.map +1 -0
  7. package/dist/cells/fit.d.ts +6 -0
  8. package/dist/cells/fit.d.ts.map +1 -0
  9. package/dist/cells/fit.js +44 -0
  10. package/dist/cells/fit.js.map +1 -0
  11. package/dist/content.d.ts +17 -0
  12. package/dist/content.d.ts.map +1 -0
  13. package/dist/content.js +71 -0
  14. package/dist/content.js.map +1 -0
  15. package/dist/endpoint.d.ts +90 -0
  16. package/dist/endpoint.d.ts.map +1 -0
  17. package/dist/endpoint.js +789 -0
  18. package/dist/endpoint.js.map +1 -0
  19. package/dist/entry.d.ts +36 -0
  20. package/dist/entry.d.ts.map +1 -0
  21. package/dist/entry.js +409 -0
  22. package/dist/entry.js.map +1 -0
  23. package/dist/env.d.ts +38 -0
  24. package/dist/env.d.ts.map +1 -0
  25. package/dist/env.js +69 -0
  26. package/dist/env.js.map +1 -0
  27. package/dist/harness-binding.d.ts +223 -0
  28. package/dist/harness-binding.d.ts.map +1 -0
  29. package/dist/harness-binding.js +589 -0
  30. package/dist/harness-binding.js.map +1 -0
  31. package/dist/index.d.ts +17 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +17 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/manifest/index.d.ts +3 -0
  36. package/dist/manifest/index.d.ts.map +1 -0
  37. package/dist/manifest/index.js +3 -0
  38. package/dist/manifest/index.js.map +1 -0
  39. package/dist/manifest/manifest.d.ts +172 -0
  40. package/dist/manifest/manifest.d.ts.map +1 -0
  41. package/dist/manifest/manifest.js +443 -0
  42. package/dist/manifest/manifest.js.map +1 -0
  43. package/dist/manifest/render.d.ts +6 -0
  44. package/dist/manifest/render.d.ts.map +1 -0
  45. package/dist/manifest/render.js +39 -0
  46. package/dist/manifest/render.js.map +1 -0
  47. package/dist/null-harness.d.ts +32 -0
  48. package/dist/null-harness.d.ts.map +1 -0
  49. package/dist/null-harness.js +162 -0
  50. package/dist/null-harness.js.map +1 -0
  51. package/dist/program.d.ts +250 -0
  52. package/dist/program.d.ts.map +1 -0
  53. package/dist/program.js +877 -0
  54. package/dist/program.js.map +1 -0
  55. package/dist/region.d.ts +72 -0
  56. package/dist/region.d.ts.map +1 -0
  57. package/dist/region.js +92 -0
  58. package/dist/region.js.map +1 -0
  59. package/dist/registry.d.ts +57 -0
  60. package/dist/registry.d.ts.map +1 -0
  61. package/dist/registry.js +101 -0
  62. package/dist/registry.js.map +1 -0
  63. package/dist/wire/descriptor.d.ts +38 -0
  64. package/dist/wire/descriptor.d.ts.map +1 -0
  65. package/dist/wire/descriptor.js +144 -0
  66. package/dist/wire/descriptor.js.map +1 -0
  67. package/dist/wire/framing.d.ts +11 -0
  68. package/dist/wire/framing.d.ts.map +1 -0
  69. package/dist/wire/framing.js +42 -0
  70. package/dist/wire/framing.js.map +1 -0
  71. package/dist/wire/index.d.ts +4 -0
  72. package/dist/wire/index.d.ts.map +1 -0
  73. package/dist/wire/index.js +4 -0
  74. package/dist/wire/index.js.map +1 -0
  75. package/dist/wire/protocol.d.ts +255 -0
  76. package/dist/wire/protocol.d.ts.map +1 -0
  77. package/dist/wire/protocol.js +15 -0
  78. package/dist/wire/protocol.js.map +1 -0
  79. package/package.json +36 -5
@@ -0,0 +1 @@
1
+ {"version":3,"file":"endpoint.js","sourceRoot":"","sources":["../src/endpoint.ts"],"names":[],"mappings":"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","sourcesContent":["// The stub's sidecar endpoint (abaigrammar section 6.3): the receiving end a\n// harness in another process connects to. Wire protocol v1 over a Unix\n// socket, listening from startup so an outside harness reaches a running\n// program that never calls a touchpoint, and so a lost connection is\n// restored by the harness connecting again.\n//\n// One binding, many connections. The first connection attaches the program\n// (one DirectBinding, which every channel runs through); the last one\n// leaving detaches it, so what was open settles as detached. Every act is\n// audited under the connection that made it. Decisions go to the one\n// connection that claimed them; turns and touchpoints are broadcast, and\n// the first end settles one.\n//\n// Nothing here keeps the program alive, and nothing here lets it die\n// mid-touchpoint: the server and its sockets are unref'd, so a program whose\n// work is done exits with a harness still connected, while a pending\n// decision, turn or touchpoint holds a ref'd timer of its own in the binding.\nimport { Buffer } from \"node:buffer\";\nimport { existsSync, unlinkSync } from \"node:fs\";\nimport { createServer, type Server, type Socket } from \"node:net\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport {\n\tCallError,\n\ttype CallErrorCode,\n\ttype Consent,\n\ttype DecisionRequest,\n\ttype DirectBinding,\n\ttype LiveEvent,\n\ttype TouchpointRequest,\n\ttype TurnRequest,\n} from \"./harness-binding.ts\";\nimport { durationMs } from \"./manifest/manifest.ts\";\nimport type { Abaigram } from \"./program.ts\";\nimport {\n\tassertSocketPathLength,\n\tattachCappedLineReader,\n\tDEFAULT_MAX_LINE_BYTES,\n\tdefaultSocketPath,\n\tEXTENSIONS,\n\tensureRunDir,\n\ttype HelloMessage,\n\tMAX_SOCKET_PATH_BYTES,\n\tPROTOCOL_VERSION,\n\tremoveDescriptor,\n\ttype WireErrorCode,\n\ttype WireResponse,\n\twriteDescriptor,\n} from \"./wire/index.ts\";\n\n/**\n * Where the socket goes when the run directory's own path is too long for\n * one (103 bytes on macOS, and a run directory under a deep project path\n * gets there): a private directory under the machine's temp dir. The\n * descriptor in the run directory names the socket wherever it is, which is\n * what its `socket` field is for, so discovery is unchanged.\n */\nexport function shortSocketPath(pid: number): string {\n\t// per user: the temp dir is shared on Linux, and the directory is made private to whoever creates it\n\tconst uid = typeof process.getuid === \"function\" ? String(process.getuid()) : \"u\";\n\treturn join(tmpdir(), `abai-sockets-${uid}`, `${pid}.sock`);\n}\n\nexport interface EndpointOptions {\n\t/** Where the socket and the descriptor go. */\n\trunDir: string;\n\t/** The socket path; default `<runDir>/<pid>.sock`. */\n\tsocketPath?: string;\n\t/** A connection whose unsent output exceeds this many bytes is dropped whole. Default 16 MiB. */\n\tmaxBuffered?: number;\n\t/** An input line past this many bytes drops the connection. Default 64 MiB. */\n\tmaxLineBytes?: number;\n}\n\n/** Unsent bytes a connection may hold before it is dropped: a harness that cannot keep up is not the program's problem. */\nexport const DEFAULT_MAX_BUFFERED = 16 * 1024 * 1024;\n/** Consecutive claim timeouts after which a connection's claims are released: a harness that never answers holds nothing. */\nexport const CONSECUTIVE_TIMEOUTS_LIMIT = 3;\n/** How long a socket gets to flush when the endpoint closes it. */\nconst CLOSE_GRACE_MS = 200;\n\ninterface Connection {\n\tid: string;\n\tsocket: Socket;\n\t/** The event filter: `include` restricts to the listed types; `exclude` drops them. */\n\tinclude: Set<string> | undefined;\n\texclude: Set<string>;\n\tclaims: Set<string>;\n\t/** A claim's own wait, never longer than the manifest's. */\n\tclaimTimeoutMs: number | undefined;\n\tconsecutiveTimeouts: number;\n\t/** Bumped on every timeout; a hook sent before the last timeout counts once with its batch. */\n\ttimeoutEpoch: number;\n\tdetachReader: () => void;\n}\n\ninterface PendingHook {\n\tid: string;\n\tname: string;\n\tconnection: Connection;\n\tepochAtSend: number;\n\t/** The claim's shorter wait, when it has one. */\n\ttimer: NodeJS.Timeout | undefined;\n}\n\nfunction errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction line(value: unknown): string {\n\treturn `${JSON.stringify(value)}\\n`;\n}\n\nexport class Endpoint {\n\treadonly runDir: string;\n\treadonly socketPath: string;\n\t/** Resolves once the socket listens and the descriptor is written; rejects with why it could not. */\n\treadonly ready: Promise<void>;\n\tprivate readonly app: Abaigram;\n\tprivate readonly maxBuffered: number;\n\tprivate readonly maxLineBytes: number;\n\tprivate server: Server | undefined;\n\tprivate readonly connections = new Set<Connection>();\n\tprivate readonly claimants = new Map<string, Connection>();\n\tprivate readonly hooks = new Map<string, PendingHook>();\n\t/** Open turns and touchpoints, replayed to a connection that arrives while they are open. */\n\tprivate readonly openTurns = new Map<string, TurnRequest>();\n\tprivate readonly openTouchpoints = new Map<string, TouchpointRequest>();\n\tprivate readonly connectionWaiters: Array<() => void> = [];\n\tprivate binding: DirectBinding | undefined;\n\tprivate unsubscribe: Array<() => void> = [];\n\tprivate nextConnectionId = 1;\n\tprivate closed = false;\n\tprivate readonly onExit: () => void;\n\tprivate settleReady: { resolve: () => void; reject: (error: Error) => void } | undefined;\n\n\tconstructor(app: Abaigram, options: EndpointOptions) {\n\t\tthis.app = app;\n\t\tthis.runDir = options.runDir;\n\t\tconst preferred = options.socketPath ?? defaultSocketPath(options.runDir, process.pid);\n\t\t// an explicit path is used as given; the default falls back to a short one when it does not fit\n\t\tthis.socketPath =\n\t\t\toptions.socketPath === undefined && Buffer.byteLength(preferred) > MAX_SOCKET_PATH_BYTES\n\t\t\t\t? shortSocketPath(process.pid)\n\t\t\t\t: preferred;\n\t\tthis.maxBuffered = options.maxBuffered ?? DEFAULT_MAX_BUFFERED;\n\t\tthis.maxLineBytes = options.maxLineBytes ?? DEFAULT_MAX_LINE_BYTES;\n\t\tthis.onExit = () => this.removeFiles();\n\t\tthis.ready = new Promise<void>((resolve, reject) => {\n\t\t\tthis.settleReady = { resolve, reject };\n\t\t});\n\t\tthis.listen();\n\t}\n\n\tprivate resolveReady(): void {\n\t\tconst settle = this.settleReady;\n\t\tthis.settleReady = undefined;\n\t\tsettle?.resolve();\n\t}\n\n\tprivate rejectReady(error: unknown): void {\n\t\tconst settle = this.settleReady;\n\t\tthis.settleReady = undefined;\n\t\tsettle?.reject(error instanceof Error ? error : new Error(String(error)));\n\t}\n\n\tget connectionCount(): number {\n\t\treturn this.connections.size;\n\t}\n\n\t/** The ids of the open connections, in order of arrival. */\n\tconnectionIds(): string[] {\n\t\treturn [...this.connections].map((connection) => connection.id);\n\t}\n\n\tprivate listen(): void {\n\t\ttry {\n\t\t\tassertSocketPathLength(this.socketPath);\n\t\t\tensureRunDir(this.runDir);\n\t\t\tif (this.socketPath !== defaultSocketPath(this.runDir, process.pid)) ensureRunDir(dirname(this.socketPath));\n\t\t\t// a socket file left by an earlier life of this very pid number: nobody else writes to this name.\n\t\t\t// (A second Abaigram under sidecar in the same process would take over the first one's socket here;\n\t\t\t// one program is one endpoint, and a test suite that builds several keeps them in turns mode.)\n\t\t\tif (existsSync(this.socketPath)) unlinkSync(this.socketPath);\n\t\t} catch (error) {\n\t\t\tthis.rejectReady(error);\n\t\t\treturn;\n\t\t}\n\t\tconst server = createServer((socket) => this.accept(socket));\n\t\tthis.server = server;\n\t\tserver.once(\"error\", (error) => this.rejectReady(error));\n\t\tserver.listen(this.socketPath, () => {\n\t\t\tserver.unref();\n\t\t\ttry {\n\t\t\t\twriteDescriptor(this.runDir, {\n\t\t\t\t\tpid: process.pid,\n\t\t\t\t\tsocket: this.socketPath,\n\t\t\t\t\tcwd: process.cwd(),\n\t\t\t\t\tname: this.app.name,\n\t\t\t\t\tmode: this.app.mode,\n\t\t\t\t\tstartedAt: new Date().toISOString(),\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\tserver.close();\n\t\t\t\tthis.rejectReady(error);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tprocess.once(\"exit\", this.onExit);\n\t\t\tthis.resolveReady();\n\t\t});\n\t}\n\n\t/** Resolves true as soon as a connection is open, or when one arrives within `timeoutMs`; false when none does. */\n\twaitForConnection(timeoutMs: number): Promise<boolean> {\n\t\tif (this.connections.size > 0) return Promise.resolve(true);\n\t\treturn new Promise<boolean>((resolve) => {\n\t\t\tlet settled = false;\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tconst index = this.connectionWaiters.indexOf(waiter);\n\t\t\t\tif (index !== -1) this.connectionWaiters.splice(index, 1);\n\t\t\t\tresolve(false);\n\t\t\t}, timeoutMs);\n\t\t\tconst waiter = (): void => {\n\t\t\t\tif (settled) return;\n\t\t\t\tsettled = true;\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tresolve(true);\n\t\t\t};\n\t\t\tthis.connectionWaiters.push(waiter);\n\t\t});\n\t}\n\n\t/** Stop listening, drop every connection, remove the socket and the descriptor. */\n\tclose(reason = \"the endpoint closed\"): void {\n\t\tif (this.closed) return;\n\t\tthis.closed = true;\n\t\t// closed before it listened: whoever awaits `ready` is told, rather than left waiting\n\t\tthis.rejectReady(new Error(reason));\n\t\tfor (const connection of [...this.connections]) this.drop(connection, reason);\n\t\tthis.server?.close();\n\t\tthis.removeFiles();\n\t\tprocess.off(\"exit\", this.onExit);\n\t}\n\n\tprivate removeFiles(): void {\n\t\ttry {\n\t\t\tremoveDescriptor(this.runDir, process.pid);\n\t\t} catch {\n\t\t\t// nothing to remove\n\t\t}\n\t\ttry {\n\t\t\tif (existsSync(this.socketPath)) unlinkSync(this.socketPath);\n\t\t} catch {\n\t\t\t// a socket file that cannot be removed is pruned by the next listing\n\t\t}\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Connections\n\t// -----------------------------------------------------------------------\n\n\tprivate accept(socket: Socket): void {\n\t\tif (this.closed) {\n\t\t\tsocket.destroy();\n\t\t\treturn;\n\t\t}\n\t\t// a connected harness never holds the program open; what holds it is the program's own pending work\n\t\tsocket.unref();\n\t\tsocket.setNoDelay?.(true);\n\t\tconst connection: Connection = {\n\t\t\tid: `k${this.nextConnectionId++}`,\n\t\t\tsocket,\n\t\t\tinclude: undefined,\n\t\t\texclude: new Set(),\n\t\t\tclaims: new Set(),\n\t\t\tclaimTimeoutMs: undefined,\n\t\t\tconsecutiveTimeouts: 0,\n\t\t\ttimeoutEpoch: 0,\n\t\t\tdetachReader: () => {},\n\t\t};\n\t\tlet binding: DirectBinding;\n\t\ttry {\n\t\t\tbinding = this.bindingFor(connection);\n\t\t} catch (error) {\n\t\t\t// the program is attached some other way (an in-process harness): this connection cannot be served,\n\t\t\t// and the one line saying so is flushed before the socket ends\n\t\t\tsocket.end(\n\t\t\t\tline({ type: \"response\", command: \"hello\", success: false, error: errorMessage(error), code: \"error\" }),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tsocket.on(\"error\", () => this.drop(connection, \"the connection failed\"));\n\t\tsocket.on(\"close\", () => this.drop(connection, \"the connection closed\"));\n\t\tconnection.detachReader = attachCappedLineReader(\n\t\t\tsocket,\n\t\t\tthis.maxLineBytes,\n\t\t\t(text) => this.onLine(connection, text),\n\t\t\t() => this.drop(connection, `a line exceeded ${this.maxLineBytes} bytes`),\n\t\t);\n\t\tthis.connections.add(connection);\n\t\tthis.write(connection, line(this.hello(connection, binding)));\n\t\t// a harness that connects while the program waits at a touchpoint or a turn is told at once\n\t\tfor (const turn of this.openTurns.values()) this.write(connection, line(this.turnMessage(turn)));\n\t\tfor (const touchpoint of this.openTouchpoints.values()) {\n\t\t\tthis.write(connection, line(this.touchpointMessage(touchpoint)));\n\t\t}\n\t\tfor (const waiter of this.connectionWaiters.splice(0)) waiter();\n\t}\n\n\t/** The one binding every connection shares, created by the first. Its own label is for acts no connection made. */\n\tprivate bindingFor(_connection: Connection): DirectBinding {\n\t\tif (this.binding) return this.binding;\n\t\tconst binding = this.app.bind(\"endpoint\");\n\t\tthis.binding = binding;\n\t\tthis.unsubscribe = [\n\t\t\tbinding.on(\"event\", (event) => this.broadcastEvent(event)),\n\t\t\tbinding.on(\"decision\", (request) => this.onDecision(request)),\n\t\t\tbinding.on(\"decision_timeout\", (id, name) => this.onDecisionTimeout(id, name)),\n\t\t\tbinding.on(\"turn\", (request) => this.onTurn(request)),\n\t\t\tbinding.on(\"touchpoint\", (request) => this.onTouchpoint(request)),\n\t\t\tbinding.on(\"detach\", (reason) => this.onDetach(reason)),\n\t\t];\n\t\treturn binding;\n\t}\n\n\tprivate hello(connection: Connection, binding: DirectBinding): HelloMessage {\n\t\tconst { manifest } = this.app;\n\t\treturn {\n\t\t\ttype: \"hello\",\n\t\t\tprotocol: PROTOCOL_VERSION,\n\t\t\tpid: process.pid,\n\t\t\tcwd: process.cwd(),\n\t\t\tmode: this.app.mode,\n\t\t\tcapabilities: {\n\t\t\t\thooks: manifest.decisions.filter((d) => d.policy !== \"forbid\").map((d) => d.name),\n\t\t\t\tcommands: manifest.capabilities.filter((c) => c.policy !== \"forbid\").map((c) => c.name),\n\t\t\t},\n\t\t\tlastSeq: this.app.region.lastSeq,\n\t\t\tconnection: connection.id,\n\t\t\tabai: {\n\t\t\t\tname: manifest.name,\n\t\t\t\tabaigrammar: manifest.abaigrammar,\n\t\t\t\tmodes: [...manifest.modes],\n\t\t\t\taudit: binding.auditInfo(),\n\t\t\t\textensions: [...EXTENSIONS],\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate write(connection: Connection, text: string): void {\n\t\tconst { socket } = connection;\n\t\tif (socket.destroyed || !socket.writable) return;\n\t\tsocket.write(text);\n\t\tif (socket.writableLength > this.maxBuffered) this.drop(connection, \"the connection fell too far behind\");\n\t}\n\n\tprivate drop(connection: Connection, reason: string): void {\n\t\tif (!this.connections.delete(connection)) return;\n\t\tconnection.detachReader();\n\t\tfor (const name of connection.claims) {\n\t\t\tif (this.claimants.get(name) === connection) this.claimants.delete(name);\n\t\t}\n\t\tconnection.claims.clear();\n\t\t// what this connection was asked, nobody will answer now\n\t\tfor (const hook of [...this.hooks.values()]) {\n\t\t\tif (hook.connection !== connection) continue;\n\t\t\tthis.forget(hook);\n\t\t\tthis.binding?.defaultDecision(hook.id, \"detached\", connection.id);\n\t\t}\n\t\tif (!connection.socket.destroyed) {\n\t\t\tconnection.socket.end();\n\t\t\tconst timer = setTimeout(() => connection.socket.destroy(), CLOSE_GRACE_MS);\n\t\t\ttimer.unref();\n\t\t}\n\t\tif (this.connections.size === 0 && this.binding) {\n\t\t\tconst binding = this.binding;\n\t\t\tthis.releaseBinding();\n\t\t\tbinding.detach(`the last harness connection closed (${reason})`);\n\t\t}\n\t}\n\n\t/** Forget the binding and everything pending on it, every timer included: a finished program must be free to exit. */\n\tprivate releaseBinding(): void {\n\t\tthis.binding = undefined;\n\t\tfor (const off of this.unsubscribe.splice(0)) off();\n\t\tfor (const hook of [...this.hooks.values()]) this.forget(hook);\n\t\tthis.openTurns.clear();\n\t\tthis.openTouchpoints.clear();\n\t}\n\n\t/** The program detached the binding itself: whoever is still connected is told by the close. */\n\tprivate onDetach(_reason: string): void {\n\t\tif (!this.binding) return;\n\t\tthis.releaseBinding();\n\t\tfor (const connection of [...this.connections]) this.drop(connection, \"the program detached\");\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Lines in\n\t// -----------------------------------------------------------------------\n\n\tprivate onLine(connection: Connection, text: string): void {\n\t\tif (text.trim() === \"\") return;\n\t\tlet message: unknown;\n\t\ttry {\n\t\t\tmessage = JSON.parse(text);\n\t\t} catch {\n\t\t\tthis.respond(connection, { type: \"response\", command: \"unknown\", success: false, error: \"invalid json\" });\n\t\t\treturn;\n\t\t}\n\t\tif (!isRecord(message)) {\n\t\t\tthis.respond(connection, { type: \"response\", command: \"unknown\", success: false, error: \"invalid message\" });\n\t\t\treturn;\n\t\t}\n\t\tconst reason = typeof message.reason === \"string\" ? message.reason : undefined;\n\t\tconst consent = isConsent(message.consent) ? message.consent : undefined;\n\t\tswitch (message.type) {\n\t\t\tcase \"request\": {\n\t\t\t\tconst id = message.id;\n\t\t\t\tif (typeof id !== \"string\" || id === \"\") {\n\t\t\t\t\tthis.respond(connection, {\n\t\t\t\t\t\ttype: \"response\",\n\t\t\t\t\t\tcommand: \"request\",\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\terror: \"request id must be a non-empty string\",\n\t\t\t\t\t\tcode: \"invalid\",\n\t\t\t\t\t});\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvoid this.dispatch(connection, id, message.command, reason, consent);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase \"hook_response\":\n\t\t\t\tthis.onHookResponse(connection, message.id, message.result, reason, consent);\n\t\t\t\treturn;\n\t\t\tcase \"turn_end\":\n\t\t\t\tif (typeof message.id === \"string\") {\n\t\t\t\t\tthis.openTurns.delete(message.id);\n\t\t\t\t\tthis.binding?.endTurn(\n\t\t\t\t\t\tmessage.id,\n\t\t\t\t\t\tconnection.id,\n\t\t\t\t\t\ttypeof message.cause === \"string\" ? message.cause : undefined,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase \"touchpoint_end\":\n\t\t\t\tif (typeof message.id === \"string\") {\n\t\t\t\t\tthis.openTouchpoints.delete(message.id);\n\t\t\t\t\tthis.binding?.endTouchpoint(message.id);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tdefault:\n\t\t\t\tthis.respond(connection, {\n\t\t\t\t\ttype: \"response\",\n\t\t\t\t\t...(typeof message.id === \"string\" ? { id: message.id } : {}),\n\t\t\t\t\tcommand: \"unknown\",\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\terror: `unknown message type: ${String(message.type)}`,\n\t\t\t\t\tcode: \"unknown\",\n\t\t\t\t});\n\t\t}\n\t}\n\n\tprivate respond(connection: Connection, response: WireResponse): void {\n\t\ttry {\n\t\t\tthis.write(connection, line(response));\n\t\t} catch (error) {\n\t\t\t// a result that cannot be serialized becomes an error response; the connection stays\n\t\t\tconst failed: WireResponse = {\n\t\t\t\ttype: \"response\",\n\t\t\t\t...(response.id === undefined ? {} : { id: response.id }),\n\t\t\t\tcommand: response.command,\n\t\t\t\tsuccess: false,\n\t\t\t\terror: `the response could not be serialized: ${errorMessage(error)}`,\n\t\t\t\tcode: \"error\",\n\t\t\t};\n\t\t\tthis.write(connection, line(failed));\n\t\t}\n\t}\n\n\tprivate failure(id: string, command: string, error: string, code: WireErrorCode): WireResponse {\n\t\treturn { type: \"response\", id, command, success: false, error, code };\n\t}\n\n\t/** Run one request, answer it when it settles. Never rejects. */\n\tprivate async dispatch(\n\t\tconnection: Connection,\n\t\tid: string,\n\t\tcommand: unknown,\n\t\treason: string | undefined,\n\t\tconsent: Consent | undefined,\n\t): Promise<void> {\n\t\tif (!isRecord(command) || typeof command.type !== \"string\") {\n\t\t\tthis.respond(connection, this.failure(id, \"unknown\", \"command must be an object with a type\", \"invalid\"));\n\t\t\treturn;\n\t\t}\n\t\tconst type = command.type;\n\t\tconst binding = this.binding;\n\t\tif (!binding) {\n\t\t\tthis.respond(connection, this.failure(id, type, \"the program is no longer attached\", \"error\"));\n\t\t\treturn;\n\t\t}\n\t\tlet response: WireResponse;\n\t\ttry {\n\t\t\tswitch (type) {\n\t\t\t\tcase \"ping\":\n\t\t\t\t\tresponse = {\n\t\t\t\t\t\ttype: \"response\",\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tcommand: type,\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tdata: { pid: process.pid, ts: Date.now() },\n\t\t\t\t\t};\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"subscribe\":\n\t\t\t\t\tresponse = this.subscribe(connection, id, command);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"claim_hooks\":\n\t\t\t\t\tresponse = this.claim(connection, id, command);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"release_hooks\":\n\t\t\t\t\tresponse = this.release(connection, id, command);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"get_manifest\":\n\t\t\t\t\tresponse = { type: \"response\", id, command: type, success: true, data: { manifest: this.app.manifest } };\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"get_content\": {\n\t\t\t\t\tconst content = binding.content();\n\t\t\t\t\tconst turns: Record<string, string> = {};\n\t\t\t\t\tfor (const turn of this.app.manifest.turns) {\n\t\t\t\t\t\tconst text = content.turn(turn.name);\n\t\t\t\t\t\tif (text !== undefined) turns[turn.name] = text;\n\t\t\t\t\t}\n\t\t\t\t\tresponse = {\n\t\t\t\t\t\ttype: \"response\",\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tcommand: type,\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\tidentity: content.identity,\n\t\t\t\t\t\t\t...(content.install === undefined ? {} : { install: content.install }),\n\t\t\t\t\t\t\t...(content.use === undefined ? {} : { use: content.use }),\n\t\t\t\t\t\t\tturns,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"get_audit\": {\n\t\t\t\t\tconst limit = typeof command.limit === \"number\" && command.limit > 0 ? Math.floor(command.limit) : 100;\n\t\t\t\t\tresponse = {\n\t\t\t\t\t\ttype: \"response\",\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tcommand: type,\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\tdata: { ...binding.auditInfo(), ...binding.auditTail(limit) },\n\t\t\t\t\t};\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"get_cells\": {\n\t\t\t\t\tconst reading = binding.readCells();\n\t\t\t\t\tconst cells: Record<string, unknown> = {};\n\t\t\t\t\tfor (const [name, cell] of Object.entries(reading.cells)) cells[name] = cell.value;\n\t\t\t\t\tresponse = { type: \"response\", id, command: type, success: true, data: { seq: reading.seq, cells } };\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"lifecycle\": {\n\t\t\t\t\tif (typeof command.op !== \"string\") {\n\t\t\t\t\t\tresponse = this.failure(id, type, \"lifecycle needs an op\", \"invalid\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tconst outcome = binding.lifecycle(command.op, reason ?? \"\", consent, connection.id);\n\t\t\t\t\tresponse = outcome.ok\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\ttype: \"response\",\n\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\tcommand: type,\n\t\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\t\tdata: outcome.data ?? { op: command.op, done: true },\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: this.failure(id, type, outcome.error, outcome.code);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \"set_cell\": {\n\t\t\t\t\tif (typeof command.name !== \"string\") {\n\t\t\t\t\t\tresponse = this.failure(id, type, \"set_cell needs a cell name\", \"invalid\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tconst outcome = await binding.writeKnob(\n\t\t\t\t\t\tcommand.name,\n\t\t\t\t\t\tcommand.value,\n\t\t\t\t\t\treason ?? \"\",\n\t\t\t\t\t\tconsent,\n\t\t\t\t\t\tconnection.id,\n\t\t\t\t\t);\n\t\t\t\t\tresponse =\n\t\t\t\t\t\toutcome.outcome === \"done\"\n\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\ttype: \"response\",\n\t\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\t\tcommand: type,\n\t\t\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\t\t\tdata: { name: command.name, value: outcome.value },\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t: this.failure(\n\t\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\t\ttype,\n\t\t\t\t\t\t\t\t\toutcome.error ?? `${command.name} was not written`,\n\t\t\t\t\t\t\t\t\toutcome.code ?? \"error\",\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\tconst { type: _type, ...params } = command;\n\t\t\t\t\tconst result = await binding.call(type, params, reason ?? \"\", consent, connection.id);\n\t\t\t\t\tresponse = { type: \"response\", id, command: type, success: true, data: result };\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst code: CallErrorCode = error instanceof CallError ? error.code : \"error\";\n\t\t\tresponse = this.failure(id, type, errorMessage(error), code);\n\t\t}\n\t\tthis.respond(connection, response);\n\t}\n\n\tprivate subscribe(connection: Connection, id: string, command: Record<string, unknown>): WireResponse {\n\t\tconst names = (value: unknown): string[] | undefined =>\n\t\t\tArray.isArray(value) && value.every((v) => typeof v === \"string\") ? (value as string[]) : undefined;\n\t\tconst include = command.include === undefined ? undefined : names(command.include);\n\t\tconst exclude = command.exclude === undefined ? [] : names(command.exclude);\n\t\tif ((command.include !== undefined && include === undefined) || exclude === undefined) {\n\t\t\treturn this.failure(id, \"subscribe\", \"include and exclude must be arrays of event names\", \"invalid\");\n\t\t}\n\t\tconnection.include = include === undefined ? undefined : new Set(include);\n\t\tconnection.exclude = new Set(exclude);\n\t\treturn {\n\t\t\ttype: \"response\",\n\t\t\tid,\n\t\t\tcommand: \"subscribe\",\n\t\t\tsuccess: true,\n\t\t\tdata: { ...(include === undefined ? {} : { include }), exclude },\n\t\t};\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Events\n\t// -----------------------------------------------------------------------\n\n\tprivate accepts(connection: Connection, name: string): boolean {\n\t\tif (connection.include !== undefined && !connection.include.has(name)) return false;\n\t\treturn !connection.exclude.has(name);\n\t}\n\n\tprivate broadcastEvent(event: LiveEvent): void {\n\t\tconst targets = [...this.connections].filter((connection) => this.accepts(connection, event.name));\n\t\tif (targets.length === 0) return;\n\t\tlet text: string;\n\t\ttry {\n\t\t\ttext = line({\n\t\t\t\ttype: \"event\",\n\t\t\t\tseq: event.seq,\n\t\t\t\tts: event.ts,\n\t\t\t\tevent: { type: event.name, ...(event.payload ?? {}) },\n\t\t\t\t...(event.truncated ? { truncated: true } : {}),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\ttext = line({\n\t\t\t\ttype: \"serialize_error\",\n\t\t\t\tseq: event.seq,\n\t\t\t\tts: event.ts,\n\t\t\t\teventType: event.name,\n\t\t\t\terror: errorMessage(error),\n\t\t\t});\n\t\t}\n\t\tfor (const connection of targets) this.write(connection, text);\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Decisions as hooks\n\t// -----------------------------------------------------------------------\n\n\tprivate claim(connection: Connection, id: string, command: Record<string, unknown>): WireResponse {\n\t\tconst hooks = command.hooks;\n\t\tconst declared = new Map(this.app.manifest.decisions.map((d) => [d.name, d]));\n\t\tif (!Array.isArray(hooks) || hooks.length === 0 || !hooks.every((h) => typeof h === \"string\")) {\n\t\t\treturn this.failure(id, \"claim_hooks\", \"hooks must be a non-empty array of decision names\", \"invalid\");\n\t\t}\n\t\tconst timeoutMs = command.timeoutMs;\n\t\tif (timeoutMs !== undefined && (typeof timeoutMs !== \"number\" || !Number.isInteger(timeoutMs) || timeoutMs < 1)) {\n\t\t\treturn this.failure(id, \"claim_hooks\", \"timeoutMs must be a positive integer\", \"invalid\");\n\t\t}\n\t\t// all or nothing: every name is checked before any is taken\n\t\tfor (const name of hooks as string[]) {\n\t\t\tconst decl = declared.get(name);\n\t\t\tif (!decl) return this.failure(id, \"claim_hooks\", `unknown decision: ${name}`, \"unknown\");\n\t\t\tif (decl.policy === \"forbid\") {\n\t\t\t\treturn this.failure(id, \"claim_hooks\", `decision ${name} is forbidden by policy`, \"forbidden\");\n\t\t\t}\n\t\t\tconst holder = this.claimants.get(name);\n\t\t\tif (holder !== undefined && holder !== connection) {\n\t\t\t\treturn this.failure(id, \"claim_hooks\", `decision ${name} is held by connection ${holder.id}`, \"denied\");\n\t\t\t}\n\t\t}\n\t\tfor (const name of hooks as string[]) {\n\t\t\tthis.claimants.set(name, connection);\n\t\t\tconnection.claims.add(name);\n\t\t}\n\t\t// the wait in force: the claim's own, which may only shorten the shortest declared among what it holds\n\t\tconst shortest = Math.min(\n\t\t\t...[...connection.claims].map((name) => durationMs(declared.get(name)?.timeout ?? \"30s\")),\n\t\t);\n\t\tif (timeoutMs !== undefined) connection.claimTimeoutMs = Math.min(timeoutMs, shortest);\n\t\treturn {\n\t\t\ttype: \"response\",\n\t\t\tid,\n\t\t\tcommand: \"claim_hooks\",\n\t\t\tsuccess: true,\n\t\t\tdata: { hooks: [...connection.claims], timeoutMs: Math.min(connection.claimTimeoutMs ?? shortest, shortest) },\n\t\t};\n\t}\n\n\tprivate release(connection: Connection, id: string, command: Record<string, unknown>): WireResponse {\n\t\tlet names: string[];\n\t\tif (command.hooks === undefined) names = [...connection.claims];\n\t\telse if (Array.isArray(command.hooks) && command.hooks.every((h) => typeof h === \"string\")) {\n\t\t\tnames = command.hooks as string[];\n\t\t} else return this.failure(id, \"release_hooks\", \"hooks must be an array of decision names\", \"invalid\");\n\t\tconst released = this.releaseClaims(connection, names);\n\t\treturn { type: \"response\", id, command: \"release_hooks\", success: true, data: { released } };\n\t}\n\n\t/** Free some of a connection's claims; what it was asked under them takes the default now. */\n\tprivate releaseClaims(connection: Connection, names: string[]): string[] {\n\t\tconst released: string[] = [];\n\t\tfor (const name of names) {\n\t\t\tif (!connection.claims.has(name)) continue;\n\t\t\tconnection.claims.delete(name);\n\t\t\tif (this.claimants.get(name) === connection) this.claimants.delete(name);\n\t\t\treleased.push(name);\n\t\t}\n\t\tfor (const hook of [...this.hooks.values()]) {\n\t\t\tif (hook.connection !== connection || !released.includes(hook.name)) continue;\n\t\t\tthis.forget(hook);\n\t\t\t// for this decision its claimant is gone, which is what detached means (section 5.4)\n\t\t\tthis.binding?.defaultDecision(hook.id, \"detached\", connection.id);\n\t\t}\n\t\treturn released;\n\t}\n\n\tprivate forget(hook: PendingHook): void {\n\t\tthis.hooks.delete(hook.id);\n\t\tif (hook.timer !== undefined) clearTimeout(hook.timer);\n\t}\n\n\t/** The program asked a decision: it goes to the claimant, or takes its default now. */\n\tprivate onDecision(request: DecisionRequest): void {\n\t\tconst binding = this.binding;\n\t\tif (!binding) return;\n\t\tconst connection = this.claimants.get(request.name);\n\t\tif (!connection) {\n\t\t\tbinding.defaultDecision(request.id, \"no_harness\");\n\t\t\treturn;\n\t\t}\n\t\tbinding.assignDecision(request.id, connection.id);\n\t\tconst remaining = Math.max(0, request.deadline - this.app.now());\n\t\tconst timeoutMs =\n\t\t\tconnection.claimTimeoutMs === undefined ? remaining : Math.min(remaining, connection.claimTimeoutMs);\n\t\tlet text: string;\n\t\ttry {\n\t\t\ttext = line({ type: \"hook\", id: request.id, hook: request.name, timeoutMs, payload: request.context });\n\t\t} catch (error) {\n\t\t\t// the context cannot cross: the claimant is told, and the program goes on with the default\n\t\t\tconst message = `payload could not be serialized: ${errorMessage(error)}`;\n\t\t\tthis.write(connection, line({ type: \"hook_rejected\", id: request.id, hook: request.name, error: message }));\n\t\t\tbinding.defaultDecision(request.id, \"invalid\", connection.id);\n\t\t\treturn;\n\t\t}\n\t\tconst hook: PendingHook = {\n\t\t\tid: request.id,\n\t\t\tname: request.name,\n\t\t\tconnection,\n\t\t\tepochAtSend: connection.timeoutEpoch,\n\t\t\ttimer: undefined,\n\t\t};\n\t\tif (timeoutMs < remaining) {\n\t\t\t// the claim's own wait, shorter than the manifest's: the default is applied then, through the one path\n\t\t\thook.timer = setTimeout(() => binding.defaultDecision(request.id, \"timeout\", connection.id), timeoutMs);\n\t\t}\n\t\tthis.hooks.set(request.id, hook);\n\t\tthis.write(connection, text);\n\t}\n\n\t/** The binding settled a decision by timeout (its deadline, or the claim's wait through `defaultDecision`). */\n\tprivate onDecisionTimeout(id: string, name: string): void {\n\t\tconst hook = this.hooks.get(id);\n\t\tif (!hook) return;\n\t\tthis.forget(hook);\n\t\tconst { connection } = hook;\n\t\tthis.write(connection, line({ type: \"hook_timeout\", id, hook: name }));\n\t\t// a batch that timed out together counts once\n\t\tif (hook.epochAtSend === connection.timeoutEpoch) connection.consecutiveTimeouts += 1;\n\t\tconnection.timeoutEpoch += 1;\n\t\tif (connection.consecutiveTimeouts >= CONSECUTIVE_TIMEOUTS_LIMIT) {\n\t\t\tconnection.consecutiveTimeouts = 0;\n\t\t\tconst released = this.releaseClaims(connection, [...connection.claims]);\n\t\t\tthis.write(connection, line({ type: \"hook_claims_released\", reason: \"timeouts\", hooks: released }));\n\t\t}\n\t}\n\n\tprivate onHookResponse(\n\t\tconnection: Connection,\n\t\tid: unknown,\n\t\tresult: unknown,\n\t\treason: string | undefined,\n\t\tconsent: Consent | undefined,\n\t): void {\n\t\tif (typeof id !== \"string\") return;\n\t\tconst hook = this.hooks.get(id);\n\t\t// ignored unless this very connection was asked: a late or a stray answer writes nothing\n\t\tif (!hook || hook.connection !== connection) return;\n\t\tthis.forget(hook);\n\t\ttry {\n\t\t\tthis.binding?.answerDecision(\n\t\t\t\tid,\n\t\t\t\tresult ?? null,\n\t\t\t\treason ?? \"no reason stated by the harness\",\n\t\t\t\tconsent,\n\t\t\t\tconnection.id,\n\t\t\t);\n\t\t\t// only an accepted answer resets the streak\n\t\t\tconnection.consecutiveTimeouts = 0;\n\t\t} catch (error) {\n\t\t\tthis.write(connection, line({ type: \"hook_rejected\", id, hook: hook.name, error: errorMessage(error) }));\n\t\t}\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Turns and touchpoints, broadcast\n\t// -----------------------------------------------------------------------\n\n\tprivate turnMessage(request: TurnRequest) {\n\t\treturn {\n\t\t\ttype: \"turn\",\n\t\t\tid: request.id,\n\t\t\tname: request.name,\n\t\t\ttimeoutMs: Math.max(0, request.deadline - this.app.now()),\n\t\t\t...(request.content === undefined ? {} : { content: request.content }),\n\t\t};\n\t}\n\n\tprivate touchpointMessage(request: TouchpointRequest) {\n\t\treturn {\n\t\t\ttype: \"touchpoint\",\n\t\t\tid: request.id,\n\t\t\tkind: request.kind,\n\t\t\t...(request.content === undefined ? {} : { content: request.content }),\n\t\t};\n\t}\n\n\tprivate onTurn(request: TurnRequest): void {\n\t\tthis.openTurns.set(request.id, request);\n\t\t// a turn ends on its own at its deadline, and this map must not remember it past that\n\t\tconst timer = setTimeout(\n\t\t\t() => this.openTurns.delete(request.id),\n\t\t\tMath.max(0, request.deadline - this.app.now()) + 1,\n\t\t);\n\t\ttimer.unref();\n\t\tconst text = line(this.turnMessage(request));\n\t\tfor (const connection of [...this.connections]) this.write(connection, text);\n\t}\n\n\tprivate onTouchpoint(request: TouchpointRequest): void {\n\t\tthis.openTouchpoints.set(request.id, request);\n\t\tconst text = line(this.touchpointMessage(request));\n\t\tfor (const connection of [...this.connections]) this.write(connection, text);\n\t}\n}\n\nfunction isConsent(value: unknown): value is Consent {\n\treturn value === \"approved\" || value === \"auto\" || value === \"denied\";\n}\n"]}
@@ -0,0 +1,36 @@
1
+ import { type Abaigram } from "./program.ts";
2
+ export declare const STUB_VERSION = "0.1.0";
3
+ export type CheckStatus = "ok" | "fail" | "skip";
4
+ export interface DoctorCheck {
5
+ name: string;
6
+ status: CheckStatus;
7
+ detail: string;
8
+ }
9
+ export interface DoctorReport {
10
+ ok: boolean;
11
+ root: string | null;
12
+ checks: DoctorCheck[];
13
+ }
14
+ /** Where the entry writes; injectable for tests. */
15
+ export interface EntryIo {
16
+ out(text: string): void;
17
+ err(text: string): void;
18
+ env: NodeJS.ProcessEnv;
19
+ cwd: string;
20
+ }
21
+ export declare const processIo: EntryIo;
22
+ /** The first line at which two texts differ (1-based), or undefined when equal. */
23
+ export declare function firstDifferingLine(a: string, b: string): number | undefined;
24
+ /** The offline half of `doctor` (section 4.4), plus the online half when the harness package is installed. Never throws. */
25
+ export declare function runDoctor(app: Abaigram, options?: {
26
+ root?: string;
27
+ io?: EntryIo;
28
+ online?: boolean;
29
+ }): Promise<DoctorReport>;
30
+ /**
31
+ * `<prog> abai <verb> ...`. `args` are the arguments after the program's
32
+ * own name; the first must be `abai`. Resolves to the exit code; -1 means
33
+ * the arguments were not an abai entry at all.
34
+ */
35
+ export declare function runEntry(app: Abaigram, args: string[], io?: EntryIo): Promise<number>;
36
+ //# sourceMappingURL=entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../src/entry.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,KAAK,QAAQ,EAAsC,MAAM,cAAc,CAAC;AAEjF,eAAO,MAAM,YAAY,UAAU,CAAC;AAEpC,MAAM,MAAM,WAAW,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,oDAAoD;AACpD,MAAM,WAAW,OAAO;IACvB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;CACZ;AAED,eAAO,MAAM,SAAS,EAAE,OAWvB,CAAC;AAgEF,mFAAmF;AACnF,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAS3E;AAaD,4HAA4H;AAC5H,wBAAsB,SAAS,CAC9B,GAAG,EAAE,QAAQ,EACb,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAC7D,OAAO,CAAC,YAAY,CAAC,CA2IvB;AAOD;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,OAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CAqItG","sourcesContent":["// The standard agent entry (abaigrammar section 4.4), the part the stub\n// provides itself: `<prog> abai manifest` prints the effective manifest and\n// `<prog> abai doctor` runs the offline conformance checks. The verbs that\n// need a harness (session, install, config, mcp, run) are delegated once a\n// harness binding exists; until then the usage says so. Never throws;\n// resolves to the exit code.\nimport { spawn } from \"node:child_process\";\nimport { accessSync, constants, existsSync, readFileSync, statSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { findRoot, MANIFEST_FILE } from \"./content.ts\";\nimport { ENV_HARNESS, ENV_MODE, expandHome } from \"./env.ts\";\nimport { validateManifest } from \"./manifest/manifest.ts\";\nimport { parseManifestYaml, renderManifestYaml } from \"./manifest/render.ts\";\nimport { type Abaigram, harnessBinary, importHarnessModule } from \"./program.ts\";\n\nexport const STUB_VERSION = \"0.1.0\";\n\nexport type CheckStatus = \"ok\" | \"fail\" | \"skip\";\n\nexport interface DoctorCheck {\n\tname: string;\n\tstatus: CheckStatus;\n\tdetail: string;\n}\n\nexport interface DoctorReport {\n\tok: boolean;\n\troot: string | null;\n\tchecks: DoctorCheck[];\n}\n\n/** Where the entry writes; injectable for tests. */\nexport interface EntryIo {\n\tout(text: string): void;\n\terr(text: string): void;\n\tenv: NodeJS.ProcessEnv;\n\tcwd: string;\n}\n\nexport const processIo: EntryIo = {\n\tout: (text) => {\n\t\tprocess.stdout.write(text);\n\t},\n\terr: (text) => {\n\t\tprocess.stderr.write(`${text}\\n`);\n\t},\n\tenv: process.env,\n\tget cwd() {\n\t\treturn process.cwd();\n\t},\n};\n\nfunction errorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\nfunction usageLines(entry: string): string[] {\n\treturn [\n\t\t`usage: ${entry} open a session`,\n\t\t` ${entry} install run the install touchpoint`,\n\t\t` ${entry} manifest [--json] print the effective manifest`,\n\t\t` ${entry} doctor [--root <dir>] [--offline] [--json]`,\n\t\t` ${entry} config [set ...] the machine-level model configuration`,\n\t\t` ${entry} mcp serve the agent's tools to an MCP client over stdio`,\n\t\t` ${entry} run [--auto] -- ARGS the harness starts this program as its supervised child`,\n\t\t\"\",\n\t\t\"doctor offline conformance checks: the effective manifest, the checked-in\",\n\t\t` ${MANIFEST_FILE}, the identity content, the modes, the audit directory`,\n\t\t\"\",\n\t\t\"session and install attach a harness and return when none can attach; mcp needs no model,\",\n\t\t\"since the client's own agent is this program's; run is always sidecar launch, with the whole\",\n\t\t\"lifecycle channel and the program's output observed from outside.\",\n\t];\n}\n\ninterface Flags {\n\tjson: boolean;\n\troot: string | undefined;\n\toffline: boolean;\n}\n\n/** `--flag`, `--flag value` and `--flag=value`; anything else is a usage error. */\nfunction parseFlags(args: string[], allowed: readonly string[]): Flags | string {\n\tconst flags: Flags = { json: false, root: undefined, offline: false };\n\tfor (let i = 0; i < args.length; i++) {\n\t\tconst arg = args[i];\n\t\tconst eq = arg.indexOf(\"=\");\n\t\tconst name = eq === -1 ? arg : arg.slice(0, eq);\n\t\tif (!allowed.includes(name)) return `unknown option ${arg}`;\n\t\tconst takeValue = (): string | undefined => {\n\t\t\tif (eq !== -1) return arg.slice(eq + 1);\n\t\t\ti += 1;\n\t\t\treturn args[i];\n\t\t};\n\t\tswitch (name) {\n\t\t\tcase \"--json\":\n\t\t\t\tflags.json = true;\n\t\t\t\tbreak;\n\t\t\tcase \"--offline\":\n\t\t\t\tflags.offline = true;\n\t\t\t\tbreak;\n\t\t\tcase \"--root\": {\n\t\t\t\tconst value = takeValue();\n\t\t\t\tif (value === undefined || value === \"\") return \"--root needs a directory\";\n\t\t\t\tflags.root = value;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn `unknown option ${arg}`;\n\t\t}\n\t}\n\treturn flags;\n}\n\n/** The first line at which two texts differ (1-based), or undefined when equal. */\nexport function firstDifferingLine(a: string, b: string): number | undefined {\n\tif (a === b) return undefined;\n\tconst linesA = a.split(\"\\n\");\n\tconst linesB = b.split(\"\\n\");\n\tconst n = Math.max(linesA.length, linesB.length);\n\tfor (let i = 0; i < n; i++) {\n\t\tif (linesA[i] !== linesB[i]) return i + 1;\n\t}\n\treturn n;\n}\n\n/** The first existing ancestor of a path (the path itself included). */\nfunction existingAncestor(path: string): string {\n\tlet current = path;\n\twhile (!existsSync(current)) {\n\t\tconst parent = dirname(current);\n\t\tif (parent === current) break;\n\t\tcurrent = parent;\n\t}\n\treturn current;\n}\n\n/** The offline half of `doctor` (section 4.4), plus the online half when the harness package is installed. Never throws. */\nexport async function runDoctor(\n\tapp: Abaigram,\n\toptions: { root?: string; io?: EntryIo; online?: boolean } = {},\n): Promise<DoctorReport> {\n\tconst io = options.io ?? processIo;\n\tconst checks: DoctorCheck[] = [];\n\tconst add = (name: string, status: CheckStatus, detail: string) => {\n\t\tchecks.push({ name, status, detail });\n\t};\n\tconst { manifest } = app;\n\n\tadd(\"entry\", \"ok\", `${manifest.entry} reached (abai stub ${STUB_VERSION})`);\n\n\tconst violations = validateManifest(manifest);\n\tlet rendered: string | undefined;\n\tif (violations.length === 0) {\n\t\trendered = renderManifestYaml(manifest);\n\t\tadd(\n\t\t\t\"manifest\",\n\t\t\t\"ok\",\n\t\t\t`the effective manifest validates (${manifest.cells.length} cells, ${manifest.events.length} events, ${manifest.capabilities.length} capabilities, ${manifest.decisions.length} decisions, ${manifest.turns.length} turns)`,\n\t\t);\n\t} else {\n\t\tadd(\"manifest\", \"fail\", `the effective manifest does not validate: ${violations.join(\"; \")}`);\n\t}\n\n\tconst root =\n\t\toptions.root !== undefined\n\t\t\t? resolve(io.cwd, options.root)\n\t\t\t: (findRoot(manifest.name, io.cwd) ??\n\t\t\t\t(existsSync(join(app.content.root, MANIFEST_FILE)) ? app.content.root : undefined));\n\tif (root === undefined) {\n\t\tadd(\"root\", \"skip\", `no checkout found (pass --root <dir> to check a checked-in ${MANIFEST_FILE})`);\n\t\tadd(MANIFEST_FILE, \"skip\", \"no checkout\");\n\t\tadd(\"identity\", \"skip\", \"no checkout\");\n\t} else {\n\t\tadd(\"root\", \"ok\", root);\n\t\tconst path = join(root, MANIFEST_FILE);\n\t\tif (!existsSync(path)) {\n\t\t\tadd(MANIFEST_FILE, \"fail\", `${path} is missing; run: ${manifest.entry} manifest > ${MANIFEST_FILE}`);\n\t\t} else {\n\t\t\tlet text: string | undefined;\n\t\t\ttry {\n\t\t\t\ttext = readFileSync(path, \"utf8\");\n\t\t\t} catch (error) {\n\t\t\t\tadd(MANIFEST_FILE, \"fail\", `${path} could not be read: ${errorMessage(error)}`);\n\t\t\t}\n\t\t\tif (text !== undefined) {\n\t\t\t\tlet parsed: unknown;\n\t\t\t\tlet parseError: string | undefined;\n\t\t\t\ttry {\n\t\t\t\t\tparsed = parseManifestYaml(text);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tparseError = errorMessage(error);\n\t\t\t\t}\n\t\t\t\tif (parseError !== undefined) {\n\t\t\t\t\tadd(MANIFEST_FILE, \"fail\", `${path} does not parse: ${parseError}`);\n\t\t\t\t} else {\n\t\t\t\t\tconst fileViolations = validateManifest(parsed);\n\t\t\t\t\tif (fileViolations.length > 0) {\n\t\t\t\t\t\tadd(MANIFEST_FILE, \"fail\", `${path} does not validate: ${fileViolations.join(\"; \")}`);\n\t\t\t\t\t} else if (rendered !== undefined && text !== rendered) {\n\t\t\t\t\t\tadd(\n\t\t\t\t\t\t\tMANIFEST_FILE,\n\t\t\t\t\t\t\t\"fail\",\n\t\t\t\t\t\t\t`${path} is stale: first difference at line ${firstDifferingLine(text, rendered)}; run: ${manifest.entry} manifest > ${MANIFEST_FILE}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if (rendered !== undefined) {\n\t\t\t\t\t\tadd(MANIFEST_FILE, \"ok\", `${path} validates and agrees with the code`);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tadd(MANIFEST_FILE, \"fail\", `${path} validates but the effective manifest does not`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst identity = join(root, manifest.content.identity);\n\t\ttry {\n\t\t\tif (!existsSync(identity)) add(\"identity\", \"fail\", `${identity} is missing`);\n\t\t\telse if (readFileSync(identity, \"utf8\").trim() === \"\") add(\"identity\", \"fail\", `${identity} is empty`);\n\t\t\telse add(\"identity\", \"ok\", identity);\n\t\t} catch (error) {\n\t\t\tadd(\"identity\", \"fail\", `${identity} could not be read: ${errorMessage(error)}`);\n\t\t}\n\t}\n\n\tif (app.harnessSelectionError !== undefined) add(\"harness\", \"fail\", app.harnessSelectionError);\n\telse add(\"harness\", \"ok\", `${ENV_HARNESS}: ${app.harnessSelection}`);\n\n\tconst modes = manifest.modes as string[];\n\tconst selected = io.env[ENV_MODE]?.trim();\n\tif (selected === undefined || selected === \"\") {\n\t\tadd(\"modes\", \"ok\", `declared: ${modes.join(\", \")}; default ${modes[0]}`);\n\t} else if (modes.includes(selected)) {\n\t\tadd(\"modes\", \"ok\", `${ENV_MODE}=${selected} is declared (declared: ${modes.join(\", \")})`);\n\t} else {\n\t\tadd(\n\t\t\t\"modes\",\n\t\t\t\"fail\",\n\t\t\t`${ENV_MODE}=${selected} is not declared (declared: ${modes.join(\", \")}); a plain run falls back and counts it`,\n\t\t);\n\t}\n\n\tif (app.endpoint !== undefined) {\n\t\t// under sidecar the endpoint has been listening since startup; doctor says where, or why not\n\t\ttry {\n\t\t\tawait app.endpoint.ready;\n\t\t\tadd(\"endpoint\", \"ok\", `listening at ${app.endpoint.socketPath}`);\n\t\t} catch (error) {\n\t\t\tadd(\"endpoint\", \"fail\", `the endpoint could not listen: ${errorMessage(error)}`);\n\t\t}\n\t}\n\n\ttry {\n\t\tconst auditPath = expandHome(manifest.audit.path, io.env.HOME ?? \"\");\n\t\tconst ancestor = existingAncestor(dirname(resolve(io.cwd, auditPath)));\n\t\tif (!statSync(ancestor).isDirectory()) {\n\t\t\tadd(\"audit\", \"fail\", `${ancestor} is not a directory`);\n\t\t} else {\n\t\t\taccessSync(ancestor, constants.W_OK);\n\t\t\tadd(\"audit\", \"ok\", `${auditPath} (${ancestor} is writable)`);\n\t\t}\n\t} catch (error) {\n\t\tadd(\"audit\", \"fail\", `the audit directory is not writable: ${errorMessage(error)}`);\n\t}\n\n\tif (options.online === false) {\n\t\tadd(\"online\", \"skip\", \"not asked (--offline)\");\n\t} else {\n\t\tconst harness = await importHarnessModule(io.env, manifest);\n\t\tif (!harness?.doctorOnline) {\n\t\t\tadd(\"online\", \"skip\", \"no harness is installed to check the model\");\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tfor (const check of await harness.doctorOnline(manifest, io.env))\n\t\t\t\t\tadd(check.name, check.status, check.detail);\n\t\t\t} catch (error) {\n\t\t\t\tadd(\"online\", \"fail\", `the harness's check failed: ${errorMessage(error)}`);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { ok: checks.every((check) => check.status !== \"fail\"), root: root ?? null, checks };\n}\n\nfunction printReport(report: DoctorReport, io: EntryIo): void {\n\tfor (const check of report.checks) io.out(`${check.status.padEnd(4)} ${check.name}: ${check.detail}\\n`);\n\tio.out(report.ok ? \"doctor: ok\\n\" : \"doctor: failed\\n\");\n}\n\n/**\n * `<prog> abai <verb> ...`. `args` are the arguments after the program's\n * own name; the first must be `abai`. Resolves to the exit code; -1 means\n * the arguments were not an abai entry at all.\n */\nexport async function runEntry(app: Abaigram, args: string[], io: EntryIo = processIo): Promise<number> {\n\tif (args[0] !== \"abai\") {\n\t\t// the entry is one of the five attach places (4.3): a launched program takes up its connection here,\n\t\t// before its own work, so its first touchpoint finds the agent present\n\t\tif (app.launched) await app.attach();\n\t\treturn -1;\n\t}\n\tconst { manifest } = app;\n\tconst usage = (problem?: string): number => {\n\t\tif (problem !== undefined) io.err(`${manifest.entry}: ${problem}`);\n\t\tfor (const line of usageLines(manifest.entry)) io.err(line);\n\t\treturn 2;\n\t};\n\ttry {\n\t\tconst verb = args[1];\n\t\tswitch (verb) {\n\t\t\tcase \"manifest\": {\n\t\t\t\tconst flags = parseFlags(args.slice(2), [\"--json\"]);\n\t\t\t\tif (typeof flags === \"string\") return usage(flags);\n\t\t\t\t// a selected mode the manifest does not declare is an error at the entry (section 4.4)\n\t\t\t\tconst selected = io.env[ENV_MODE]?.trim();\n\t\t\t\tif (selected !== undefined && selected !== \"\" && !(manifest.modes as string[]).includes(selected)) {\n\t\t\t\t\tio.err(\n\t\t\t\t\t\t`${manifest.entry}: ${ENV_MODE}=${selected} is not a declared mode (declared: ${manifest.modes.join(\", \")})`,\n\t\t\t\t\t);\n\t\t\t\t\treturn 2;\n\t\t\t\t}\n\t\t\t\tio.out(flags.json ? `${JSON.stringify(manifest, null, 2)}\\n` : renderManifestYaml(manifest));\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tcase \"doctor\": {\n\t\t\t\tconst flags = parseFlags(args.slice(2), [\"--json\", \"--root\", \"--offline\"]);\n\t\t\t\tif (typeof flags === \"string\") return usage(flags);\n\t\t\t\tconst report = await runDoctor(app, { root: flags.root, io, online: !flags.offline });\n\t\t\t\tif (flags.json) io.out(`${JSON.stringify(report, null, 2)}\\n`);\n\t\t\t\telse printReport(report, io);\n\t\t\t\treturn report.ok ? 0 : 1;\n\t\t\t}\n\t\t\tcase undefined:\n\t\t\tcase \"session\": {\n\t\t\t\tawait app.session();\n\t\t\t\tif (app.attached) return 0;\n\t\t\t\tio.err(`${manifest.entry}: no harness attached (${app.attachError ?? \"unknown reason\"})`);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tcase \"install\": {\n\t\t\t\tawait app.install();\n\t\t\t\tif (app.attached) return 0;\n\t\t\t\tio.err(`${manifest.entry}: no harness attached (${app.attachError ?? \"unknown reason\"})`);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tcase \"config\": {\n\t\t\t\tconst harness = await importHarnessModule(io.env, manifest);\n\t\t\t\tif (!harness?.runConfig) return usage(\"config needs the harness package, which is not installed\");\n\t\t\t\treturn await harness.runConfig(args.slice(2), io);\n\t\t\t}\n\t\t\tcase \"mcp\": {\n\t\t\t\t// the program at its entry serves an MCP client: under sidecar through the binary on this\n\t\t\t\t// process's stdio, otherwise in-process through the installed harness package (section 4.4).\n\t\t\t\t// ABAI_HARNESS is honoured like everywhere: off attaches nothing, a null harness is attached already\n\t\t\t\tif (app.harnessSelection === \"off\") {\n\t\t\t\t\tio.err(`${manifest.entry}: no harness attached (${ENV_HARNESS}=off)`);\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\tif (app.attached) {\n\t\t\t\t\tio.err(`${manifest.entry}: ${manifest.name} already has a harness attached`);\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\tif (app.endpoint !== undefined) {\n\t\t\t\t\tconst code = await app.serveMcpSidecar(app.endpoint);\n\t\t\t\t\tif (code >= 0) return code;\n\t\t\t\t\tio.err(`${manifest.entry}: no harness attached (${app.attachError ?? \"unknown reason\"})`);\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\tconst harness = await importHarnessModule(io.env, manifest);\n\t\t\t\tif (!harness?.serveMcpEmbedded) return usage(\"mcp needs the harness package, which is not installed\");\n\t\t\t\tconst binding = app.bind(\"mcp\");\n\t\t\t\tbinding.enterSafepoint();\n\t\t\t\ttry {\n\t\t\t\t\treturn await harness.serveMcpEmbedded(binding);\n\t\t\t\t} finally {\n\t\t\t\t\tbinding.leaveSafepoint();\n\t\t\t\t}\n\t\t\t}\n\t\t\tcase \"run\": {\n\t\t\t\t// sidecar launch (4.4, 6.3): the harness binary starts this very program again as its child\n\t\t\t\tif (!(manifest.modes as string[]).includes(\"sidecar\")) {\n\t\t\t\t\tio.err(\n\t\t\t\t\t\t`${manifest.entry}: run is sidecar launch, and ${manifest.name} declares ${manifest.modes.join(\", \")}`,\n\t\t\t\t\t);\n\t\t\t\t\treturn 2;\n\t\t\t\t}\n\t\t\t\tconst separator = args.indexOf(\"--\");\n\t\t\t\tconst flags = args.slice(2, separator === -1 ? undefined : separator);\n\t\t\t\tconst programArgs = separator === -1 ? [] : args.slice(separator + 1);\n\t\t\t\tfor (const flag of flags) {\n\t\t\t\t\tif (flag !== \"--auto\" && flag !== \"--deny-mutate\" && flag !== \"--all-events\") {\n\t\t\t\t\t\treturn usage(`unknown option ${flag} (run takes --auto, --deny-mutate, --all-events)`);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst binary = harnessBinary(io.env, app.content.root);\n\t\t\t\tconst script = process.argv[1];\n\t\t\t\tif (script === undefined) return usage(\"run cannot tell how this program was started\");\n\t\t\t\tconst command = [process.execPath, ...process.execArgv, script, ...programArgs];\n\t\t\t\tconst child = spawn(binary.command, [...binary.args, \"run\", ...flags, \"--\", ...command], {\n\t\t\t\t\tstdio: \"inherit\",\n\t\t\t\t\tenv: { ...process.env, ...io.env },\n\t\t\t\t});\n\t\t\t\t// whoever ends this process ends the launcher behind it, which ends the program it supervises\n\t\t\t\tconst forward = (signal: NodeJS.Signals): void => {\n\t\t\t\t\tif (child.exitCode === null && child.signalCode === null) child.kill(signal);\n\t\t\t\t};\n\t\t\t\tconst forwarded: NodeJS.Signals[] = [\"SIGTERM\", \"SIGINT\", \"SIGHUP\"];\n\t\t\t\tfor (const signal of forwarded) process.on(signal, forward);\n\t\t\t\ttry {\n\t\t\t\t\treturn await new Promise<number>((resolve) => {\n\t\t\t\t\t\tchild.once(\"error\", (error) => {\n\t\t\t\t\t\t\tio.err(`${manifest.entry}: the harness binary could not be started: ${errorMessage(error)}`);\n\t\t\t\t\t\t\tresolve(1);\n\t\t\t\t\t\t});\n\t\t\t\t\t\tchild.once(\"exit\", (code) => resolve(code ?? 1));\n\t\t\t\t\t});\n\t\t\t\t} finally {\n\t\t\t\t\tfor (const signal of forwarded) process.off(signal, forward);\n\t\t\t\t}\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn usage(`unknown verb ${verb}`);\n\t\t}\n\t} catch (error) {\n\t\tio.err(`${manifest.entry}: ${errorMessage(error)}`);\n\t\treturn 2;\n\t}\n}\n"]}
package/dist/entry.js ADDED
@@ -0,0 +1,409 @@
1
+ // The standard agent entry (abaigrammar section 4.4), the part the stub
2
+ // provides itself: `<prog> abai manifest` prints the effective manifest and
3
+ // `<prog> abai doctor` runs the offline conformance checks. The verbs that
4
+ // need a harness (session, install, config, mcp, run) are delegated once a
5
+ // harness binding exists; until then the usage says so. Never throws;
6
+ // resolves to the exit code.
7
+ import { spawn } from "node:child_process";
8
+ import { accessSync, constants, existsSync, readFileSync, statSync } from "node:fs";
9
+ import { dirname, join, resolve } from "node:path";
10
+ import { findRoot, MANIFEST_FILE } from "./content.js";
11
+ import { ENV_HARNESS, ENV_MODE, expandHome } from "./env.js";
12
+ import { validateManifest } from "./manifest/manifest.js";
13
+ import { parseManifestYaml, renderManifestYaml } from "./manifest/render.js";
14
+ import { harnessBinary, importHarnessModule } from "./program.js";
15
+ export const STUB_VERSION = "0.1.0";
16
+ export const processIo = {
17
+ out: (text) => {
18
+ process.stdout.write(text);
19
+ },
20
+ err: (text) => {
21
+ process.stderr.write(`${text}\n`);
22
+ },
23
+ env: process.env,
24
+ get cwd() {
25
+ return process.cwd();
26
+ },
27
+ };
28
+ function errorMessage(error) {
29
+ return error instanceof Error ? error.message : String(error);
30
+ }
31
+ function usageLines(entry) {
32
+ return [
33
+ `usage: ${entry} open a session`,
34
+ ` ${entry} install run the install touchpoint`,
35
+ ` ${entry} manifest [--json] print the effective manifest`,
36
+ ` ${entry} doctor [--root <dir>] [--offline] [--json]`,
37
+ ` ${entry} config [set ...] the machine-level model configuration`,
38
+ ` ${entry} mcp serve the agent's tools to an MCP client over stdio`,
39
+ ` ${entry} run [--auto] -- ARGS the harness starts this program as its supervised child`,
40
+ "",
41
+ "doctor offline conformance checks: the effective manifest, the checked-in",
42
+ ` ${MANIFEST_FILE}, the identity content, the modes, the audit directory`,
43
+ "",
44
+ "session and install attach a harness and return when none can attach; mcp needs no model,",
45
+ "since the client's own agent is this program's; run is always sidecar launch, with the whole",
46
+ "lifecycle channel and the program's output observed from outside.",
47
+ ];
48
+ }
49
+ /** `--flag`, `--flag value` and `--flag=value`; anything else is a usage error. */
50
+ function parseFlags(args, allowed) {
51
+ const flags = { json: false, root: undefined, offline: false };
52
+ for (let i = 0; i < args.length; i++) {
53
+ const arg = args[i];
54
+ const eq = arg.indexOf("=");
55
+ const name = eq === -1 ? arg : arg.slice(0, eq);
56
+ if (!allowed.includes(name))
57
+ return `unknown option ${arg}`;
58
+ const takeValue = () => {
59
+ if (eq !== -1)
60
+ return arg.slice(eq + 1);
61
+ i += 1;
62
+ return args[i];
63
+ };
64
+ switch (name) {
65
+ case "--json":
66
+ flags.json = true;
67
+ break;
68
+ case "--offline":
69
+ flags.offline = true;
70
+ break;
71
+ case "--root": {
72
+ const value = takeValue();
73
+ if (value === undefined || value === "")
74
+ return "--root needs a directory";
75
+ flags.root = value;
76
+ break;
77
+ }
78
+ default:
79
+ return `unknown option ${arg}`;
80
+ }
81
+ }
82
+ return flags;
83
+ }
84
+ /** The first line at which two texts differ (1-based), or undefined when equal. */
85
+ export function firstDifferingLine(a, b) {
86
+ if (a === b)
87
+ return undefined;
88
+ const linesA = a.split("\n");
89
+ const linesB = b.split("\n");
90
+ const n = Math.max(linesA.length, linesB.length);
91
+ for (let i = 0; i < n; i++) {
92
+ if (linesA[i] !== linesB[i])
93
+ return i + 1;
94
+ }
95
+ return n;
96
+ }
97
+ /** The first existing ancestor of a path (the path itself included). */
98
+ function existingAncestor(path) {
99
+ let current = path;
100
+ while (!existsSync(current)) {
101
+ const parent = dirname(current);
102
+ if (parent === current)
103
+ break;
104
+ current = parent;
105
+ }
106
+ return current;
107
+ }
108
+ /** The offline half of `doctor` (section 4.4), plus the online half when the harness package is installed. Never throws. */
109
+ export async function runDoctor(app, options = {}) {
110
+ const io = options.io ?? processIo;
111
+ const checks = [];
112
+ const add = (name, status, detail) => {
113
+ checks.push({ name, status, detail });
114
+ };
115
+ const { manifest } = app;
116
+ add("entry", "ok", `${manifest.entry} reached (abai stub ${STUB_VERSION})`);
117
+ const violations = validateManifest(manifest);
118
+ let rendered;
119
+ if (violations.length === 0) {
120
+ rendered = renderManifestYaml(manifest);
121
+ add("manifest", "ok", `the effective manifest validates (${manifest.cells.length} cells, ${manifest.events.length} events, ${manifest.capabilities.length} capabilities, ${manifest.decisions.length} decisions, ${manifest.turns.length} turns)`);
122
+ }
123
+ else {
124
+ add("manifest", "fail", `the effective manifest does not validate: ${violations.join("; ")}`);
125
+ }
126
+ const root = options.root !== undefined
127
+ ? resolve(io.cwd, options.root)
128
+ : (findRoot(manifest.name, io.cwd) ??
129
+ (existsSync(join(app.content.root, MANIFEST_FILE)) ? app.content.root : undefined));
130
+ if (root === undefined) {
131
+ add("root", "skip", `no checkout found (pass --root <dir> to check a checked-in ${MANIFEST_FILE})`);
132
+ add(MANIFEST_FILE, "skip", "no checkout");
133
+ add("identity", "skip", "no checkout");
134
+ }
135
+ else {
136
+ add("root", "ok", root);
137
+ const path = join(root, MANIFEST_FILE);
138
+ if (!existsSync(path)) {
139
+ add(MANIFEST_FILE, "fail", `${path} is missing; run: ${manifest.entry} manifest > ${MANIFEST_FILE}`);
140
+ }
141
+ else {
142
+ let text;
143
+ try {
144
+ text = readFileSync(path, "utf8");
145
+ }
146
+ catch (error) {
147
+ add(MANIFEST_FILE, "fail", `${path} could not be read: ${errorMessage(error)}`);
148
+ }
149
+ if (text !== undefined) {
150
+ let parsed;
151
+ let parseError;
152
+ try {
153
+ parsed = parseManifestYaml(text);
154
+ }
155
+ catch (error) {
156
+ parseError = errorMessage(error);
157
+ }
158
+ if (parseError !== undefined) {
159
+ add(MANIFEST_FILE, "fail", `${path} does not parse: ${parseError}`);
160
+ }
161
+ else {
162
+ const fileViolations = validateManifest(parsed);
163
+ if (fileViolations.length > 0) {
164
+ add(MANIFEST_FILE, "fail", `${path} does not validate: ${fileViolations.join("; ")}`);
165
+ }
166
+ else if (rendered !== undefined && text !== rendered) {
167
+ add(MANIFEST_FILE, "fail", `${path} is stale: first difference at line ${firstDifferingLine(text, rendered)}; run: ${manifest.entry} manifest > ${MANIFEST_FILE}`);
168
+ }
169
+ else if (rendered !== undefined) {
170
+ add(MANIFEST_FILE, "ok", `${path} validates and agrees with the code`);
171
+ }
172
+ else {
173
+ add(MANIFEST_FILE, "fail", `${path} validates but the effective manifest does not`);
174
+ }
175
+ }
176
+ }
177
+ }
178
+ const identity = join(root, manifest.content.identity);
179
+ try {
180
+ if (!existsSync(identity))
181
+ add("identity", "fail", `${identity} is missing`);
182
+ else if (readFileSync(identity, "utf8").trim() === "")
183
+ add("identity", "fail", `${identity} is empty`);
184
+ else
185
+ add("identity", "ok", identity);
186
+ }
187
+ catch (error) {
188
+ add("identity", "fail", `${identity} could not be read: ${errorMessage(error)}`);
189
+ }
190
+ }
191
+ if (app.harnessSelectionError !== undefined)
192
+ add("harness", "fail", app.harnessSelectionError);
193
+ else
194
+ add("harness", "ok", `${ENV_HARNESS}: ${app.harnessSelection}`);
195
+ const modes = manifest.modes;
196
+ const selected = io.env[ENV_MODE]?.trim();
197
+ if (selected === undefined || selected === "") {
198
+ add("modes", "ok", `declared: ${modes.join(", ")}; default ${modes[0]}`);
199
+ }
200
+ else if (modes.includes(selected)) {
201
+ add("modes", "ok", `${ENV_MODE}=${selected} is declared (declared: ${modes.join(", ")})`);
202
+ }
203
+ else {
204
+ add("modes", "fail", `${ENV_MODE}=${selected} is not declared (declared: ${modes.join(", ")}); a plain run falls back and counts it`);
205
+ }
206
+ if (app.endpoint !== undefined) {
207
+ // under sidecar the endpoint has been listening since startup; doctor says where, or why not
208
+ try {
209
+ await app.endpoint.ready;
210
+ add("endpoint", "ok", `listening at ${app.endpoint.socketPath}`);
211
+ }
212
+ catch (error) {
213
+ add("endpoint", "fail", `the endpoint could not listen: ${errorMessage(error)}`);
214
+ }
215
+ }
216
+ try {
217
+ const auditPath = expandHome(manifest.audit.path, io.env.HOME ?? "");
218
+ const ancestor = existingAncestor(dirname(resolve(io.cwd, auditPath)));
219
+ if (!statSync(ancestor).isDirectory()) {
220
+ add("audit", "fail", `${ancestor} is not a directory`);
221
+ }
222
+ else {
223
+ accessSync(ancestor, constants.W_OK);
224
+ add("audit", "ok", `${auditPath} (${ancestor} is writable)`);
225
+ }
226
+ }
227
+ catch (error) {
228
+ add("audit", "fail", `the audit directory is not writable: ${errorMessage(error)}`);
229
+ }
230
+ if (options.online === false) {
231
+ add("online", "skip", "not asked (--offline)");
232
+ }
233
+ else {
234
+ const harness = await importHarnessModule(io.env, manifest);
235
+ if (!harness?.doctorOnline) {
236
+ add("online", "skip", "no harness is installed to check the model");
237
+ }
238
+ else {
239
+ try {
240
+ for (const check of await harness.doctorOnline(manifest, io.env))
241
+ add(check.name, check.status, check.detail);
242
+ }
243
+ catch (error) {
244
+ add("online", "fail", `the harness's check failed: ${errorMessage(error)}`);
245
+ }
246
+ }
247
+ }
248
+ return { ok: checks.every((check) => check.status !== "fail"), root: root ?? null, checks };
249
+ }
250
+ function printReport(report, io) {
251
+ for (const check of report.checks)
252
+ io.out(`${check.status.padEnd(4)} ${check.name}: ${check.detail}\n`);
253
+ io.out(report.ok ? "doctor: ok\n" : "doctor: failed\n");
254
+ }
255
+ /**
256
+ * `<prog> abai <verb> ...`. `args` are the arguments after the program's
257
+ * own name; the first must be `abai`. Resolves to the exit code; -1 means
258
+ * the arguments were not an abai entry at all.
259
+ */
260
+ export async function runEntry(app, args, io = processIo) {
261
+ if (args[0] !== "abai") {
262
+ // the entry is one of the five attach places (4.3): a launched program takes up its connection here,
263
+ // before its own work, so its first touchpoint finds the agent present
264
+ if (app.launched)
265
+ await app.attach();
266
+ return -1;
267
+ }
268
+ const { manifest } = app;
269
+ const usage = (problem) => {
270
+ if (problem !== undefined)
271
+ io.err(`${manifest.entry}: ${problem}`);
272
+ for (const line of usageLines(manifest.entry))
273
+ io.err(line);
274
+ return 2;
275
+ };
276
+ try {
277
+ const verb = args[1];
278
+ switch (verb) {
279
+ case "manifest": {
280
+ const flags = parseFlags(args.slice(2), ["--json"]);
281
+ if (typeof flags === "string")
282
+ return usage(flags);
283
+ // a selected mode the manifest does not declare is an error at the entry (section 4.4)
284
+ const selected = io.env[ENV_MODE]?.trim();
285
+ if (selected !== undefined && selected !== "" && !manifest.modes.includes(selected)) {
286
+ io.err(`${manifest.entry}: ${ENV_MODE}=${selected} is not a declared mode (declared: ${manifest.modes.join(", ")})`);
287
+ return 2;
288
+ }
289
+ io.out(flags.json ? `${JSON.stringify(manifest, null, 2)}\n` : renderManifestYaml(manifest));
290
+ return 0;
291
+ }
292
+ case "doctor": {
293
+ const flags = parseFlags(args.slice(2), ["--json", "--root", "--offline"]);
294
+ if (typeof flags === "string")
295
+ return usage(flags);
296
+ const report = await runDoctor(app, { root: flags.root, io, online: !flags.offline });
297
+ if (flags.json)
298
+ io.out(`${JSON.stringify(report, null, 2)}\n`);
299
+ else
300
+ printReport(report, io);
301
+ return report.ok ? 0 : 1;
302
+ }
303
+ case undefined:
304
+ case "session": {
305
+ await app.session();
306
+ if (app.attached)
307
+ return 0;
308
+ io.err(`${manifest.entry}: no harness attached (${app.attachError ?? "unknown reason"})`);
309
+ return 1;
310
+ }
311
+ case "install": {
312
+ await app.install();
313
+ if (app.attached)
314
+ return 0;
315
+ io.err(`${manifest.entry}: no harness attached (${app.attachError ?? "unknown reason"})`);
316
+ return 1;
317
+ }
318
+ case "config": {
319
+ const harness = await importHarnessModule(io.env, manifest);
320
+ if (!harness?.runConfig)
321
+ return usage("config needs the harness package, which is not installed");
322
+ return await harness.runConfig(args.slice(2), io);
323
+ }
324
+ case "mcp": {
325
+ // the program at its entry serves an MCP client: under sidecar through the binary on this
326
+ // process's stdio, otherwise in-process through the installed harness package (section 4.4).
327
+ // ABAI_HARNESS is honoured like everywhere: off attaches nothing, a null harness is attached already
328
+ if (app.harnessSelection === "off") {
329
+ io.err(`${manifest.entry}: no harness attached (${ENV_HARNESS}=off)`);
330
+ return 1;
331
+ }
332
+ if (app.attached) {
333
+ io.err(`${manifest.entry}: ${manifest.name} already has a harness attached`);
334
+ return 1;
335
+ }
336
+ if (app.endpoint !== undefined) {
337
+ const code = await app.serveMcpSidecar(app.endpoint);
338
+ if (code >= 0)
339
+ return code;
340
+ io.err(`${manifest.entry}: no harness attached (${app.attachError ?? "unknown reason"})`);
341
+ return 1;
342
+ }
343
+ const harness = await importHarnessModule(io.env, manifest);
344
+ if (!harness?.serveMcpEmbedded)
345
+ return usage("mcp needs the harness package, which is not installed");
346
+ const binding = app.bind("mcp");
347
+ binding.enterSafepoint();
348
+ try {
349
+ return await harness.serveMcpEmbedded(binding);
350
+ }
351
+ finally {
352
+ binding.leaveSafepoint();
353
+ }
354
+ }
355
+ case "run": {
356
+ // sidecar launch (4.4, 6.3): the harness binary starts this very program again as its child
357
+ if (!manifest.modes.includes("sidecar")) {
358
+ io.err(`${manifest.entry}: run is sidecar launch, and ${manifest.name} declares ${manifest.modes.join(", ")}`);
359
+ return 2;
360
+ }
361
+ const separator = args.indexOf("--");
362
+ const flags = args.slice(2, separator === -1 ? undefined : separator);
363
+ const programArgs = separator === -1 ? [] : args.slice(separator + 1);
364
+ for (const flag of flags) {
365
+ if (flag !== "--auto" && flag !== "--deny-mutate" && flag !== "--all-events") {
366
+ return usage(`unknown option ${flag} (run takes --auto, --deny-mutate, --all-events)`);
367
+ }
368
+ }
369
+ const binary = harnessBinary(io.env, app.content.root);
370
+ const script = process.argv[1];
371
+ if (script === undefined)
372
+ return usage("run cannot tell how this program was started");
373
+ const command = [process.execPath, ...process.execArgv, script, ...programArgs];
374
+ const child = spawn(binary.command, [...binary.args, "run", ...flags, "--", ...command], {
375
+ stdio: "inherit",
376
+ env: { ...process.env, ...io.env },
377
+ });
378
+ // whoever ends this process ends the launcher behind it, which ends the program it supervises
379
+ const forward = (signal) => {
380
+ if (child.exitCode === null && child.signalCode === null)
381
+ child.kill(signal);
382
+ };
383
+ const forwarded = ["SIGTERM", "SIGINT", "SIGHUP"];
384
+ for (const signal of forwarded)
385
+ process.on(signal, forward);
386
+ try {
387
+ return await new Promise((resolve) => {
388
+ child.once("error", (error) => {
389
+ io.err(`${manifest.entry}: the harness binary could not be started: ${errorMessage(error)}`);
390
+ resolve(1);
391
+ });
392
+ child.once("exit", (code) => resolve(code ?? 1));
393
+ });
394
+ }
395
+ finally {
396
+ for (const signal of forwarded)
397
+ process.off(signal, forward);
398
+ }
399
+ }
400
+ default:
401
+ return usage(`unknown verb ${verb}`);
402
+ }
403
+ }
404
+ catch (error) {
405
+ io.err(`${manifest.entry}: ${errorMessage(error)}`);
406
+ return 2;
407
+ }
408
+ }
409
+ //# sourceMappingURL=entry.js.map