@agentorg/cli 0.0.1 → 0.0.2

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 (90) hide show
  1. package/README.md +3 -3
  2. package/dist/src/bindings/mcp/encoding.js +1 -4
  3. package/dist/src/clients/cli/commands.js +1 -1
  4. package/dist/src/clients/cli/index.js +1 -1
  5. package/dist/src/clients/mcp/agent.d.ts +3 -5
  6. package/dist/src/clients/mcp/agent.js +10 -23
  7. package/dist/src/clients/mcp/command.d.ts +1 -1
  8. package/dist/src/clients/mcp/command.js +5 -11
  9. package/dist/src/clients/mcp/projects.d.ts +1 -2
  10. package/dist/src/clients/mcp/projects.js +5 -9
  11. package/dist/src/clients/mcp/sessions.d.ts +1 -5
  12. package/dist/src/clients/mcp/sessions.js +1 -10
  13. package/dist/src/clients/mcp/setup.js +4 -8
  14. package/dist/src/clients/mcp/waiter.d.ts +0 -2
  15. package/dist/src/clients/mcp/waiter.js +9 -20
  16. package/dist/src/domain/actors.js +3 -7
  17. package/dist/src/domain/attention.d.ts +8 -7
  18. package/dist/src/domain/attention.js +31 -47
  19. package/dist/src/domain/capabilities.js +0 -1
  20. package/dist/src/domain/claims.js +2 -2
  21. package/dist/src/domain/errors.d.ts +1 -1
  22. package/dist/src/domain/errors.js +1 -1
  23. package/dist/src/domain/index.d.ts +1 -15
  24. package/dist/src/domain/model/attention.d.ts +1 -5
  25. package/dist/src/domain/model/attention.js +5 -6
  26. package/dist/src/domain/model/builtins.d.ts +12 -179
  27. package/dist/src/domain/model/builtins.js +3 -6
  28. package/dist/src/domain/model/claims.d.ts +1 -3
  29. package/dist/src/domain/model/claims.js +1 -3
  30. package/dist/src/domain/model/index.d.ts +0 -7
  31. package/dist/src/domain/model/index.js +0 -3
  32. package/dist/src/domain/model/json-schema.d.ts +1 -4
  33. package/dist/src/domain/model/records.d.ts +0 -3
  34. package/dist/src/domain/model/records.js +3 -7
  35. package/dist/src/domain/model/system.d.ts +1 -5
  36. package/dist/src/domain/model/system.js +1 -5
  37. package/dist/src/domain/model/team.d.ts +4 -119
  38. package/dist/src/domain/model/team.js +8 -19
  39. package/dist/src/domain/model/workspace.d.ts +2 -86
  40. package/dist/src/domain/model/workspace.js +0 -1
  41. package/dist/src/domain/ports.d.ts +3 -4
  42. package/dist/src/domain/registry.d.ts +2 -16
  43. package/dist/src/domain/registry.js +22 -54
  44. package/dist/src/domain/system.js +1 -5
  45. package/dist/src/domain/team.d.ts +1 -1
  46. package/dist/src/domain/team.js +13 -33
  47. package/dist/src/domain/workspace.js +2 -10
  48. package/dist/src/home.d.ts +5 -5
  49. package/dist/src/home.js +6 -6
  50. package/dist/src/server/command.js +2 -2
  51. package/dist/src/server/index.d.ts +1 -1
  52. package/dist/src/server/index.js +2 -2
  53. package/dist/src/storage/sqlite/database.d.ts +5 -0
  54. package/dist/src/storage/sqlite/database.js +32 -1
  55. package/dist/src/storage/sqlite/index.js +1 -2
  56. package/dist/src/storage/sqlite/schema.d.ts +3 -4
  57. package/dist/src/storage/sqlite/schema.js +4 -4
  58. package/node_modules/@uniac/agentic-workspace/README.md +5 -5
  59. package/node_modules/@uniac/agentic-workspace/dist/examples/authority.d.ts +0 -1
  60. package/node_modules/@uniac/agentic-workspace/dist/examples/authority.js +3 -16
  61. package/node_modules/@uniac/agentic-workspace/dist/src/actors/index.d.ts +13 -13
  62. package/node_modules/@uniac/agentic-workspace/dist/src/actors/index.js +9 -25
  63. package/node_modules/@uniac/agentic-workspace/dist/src/contracts/common.d.ts +1 -9
  64. package/node_modules/@uniac/agentic-workspace/dist/src/contracts/common.js +2 -4
  65. package/node_modules/@uniac/agentic-workspace/dist/src/contracts/forms.d.ts +0 -13
  66. package/node_modules/@uniac/agentic-workspace/dist/src/contracts/forms.js +0 -3
  67. package/node_modules/@uniac/agentic-workspace/dist/src/contracts/messages.d.ts +0 -3
  68. package/node_modules/@uniac/agentic-workspace/dist/src/contracts/messages.js +3 -3
  69. package/node_modules/@uniac/agentic-workspace/dist/src/contracts/work.d.ts +2 -15
  70. package/node_modules/@uniac/agentic-workspace/dist/src/contracts/work.js +9 -14
  71. package/node_modules/@uniac/agentic-workspace/dist/src/mcp/index.js +1 -1
  72. package/node_modules/@uniac/agentic-workspace/dist/src/persistence/index.d.ts +1 -4
  73. package/node_modules/@uniac/agentic-workspace/dist/src/persistence/sqlite.js +2 -15
  74. package/node_modules/@uniac/agentic-workspace/dist/src/records.d.ts +0 -7
  75. package/node_modules/@uniac/agentic-workspace/dist/src/records.js +0 -14
  76. package/node_modules/@uniac/agentic-workspace/dist/src/work/asks.d.ts +20 -19
  77. package/node_modules/@uniac/agentic-workspace/dist/src/work/asks.js +39 -41
  78. package/node_modules/@uniac/agentic-workspace/dist/src/work/index.js +18 -24
  79. package/node_modules/@uniac/agentic-workspace/docs/contracts.md +23 -29
  80. package/node_modules/@uniac/agentic-workspace/docs/design.md +13 -13
  81. package/node_modules/@uniac/agentic-workspace/docs/hub-integration.md +25 -50
  82. package/node_modules/@uniac/agentic-workspace/package.json +1 -1
  83. package/package.json +3 -3
  84. package/skills/agentorg/SKILL.md +39 -38
  85. package/skills/agentorg/references/claude-code.md +3 -4
  86. package/vendor/uniac-agentic-workspace-0.0.2-8aebc44.tgz +0 -0
  87. package/vendor/workspace.json +6 -6
  88. package/dist/src/clients/mcp/levels.d.ts +0 -17
  89. package/dist/src/clients/mcp/levels.js +0 -7
  90. package/vendor/uniac-agentic-workspace-0.0.1-26fd0ee.tgz +0 -0
package/README.md CHANGED
@@ -1,11 +1,11 @@
1
1
  # agentorg
2
2
 
3
- AgentOrg connects Actors into an organization. Each Actor is a position with a responsibility and
4
- a manager; the user is at the root. Hub keeps organizational state and exposes explicit Tools.
3
+ AgentOrg connects Actors into an organization. Each Actor is a responsibility, and every Actor sits
4
+ on one flat level; the person is the user's own Actor. Hub keeps organizational state and exposes explicit Tools.
5
5
  Actors decide how to use those Tools independently of any native execution implementation.
6
6
 
7
7
  Actors exchange Messages in pair conversations, and track shared Work with the asks on it, through
8
- Hub Tools backed by `@uniac/agentic-workspace`. Hub supplies canonical Actor identity and hierarchy,
8
+ Hub Tools backed by `@uniac/agentic-workspace`. Hub supplies canonical Actor identity, the person,
9
9
  actual connection presence and shared resource claims. An enrolled Provider can provision an
10
10
  implementation when requested at Actor creation. Human applications, agent sessions and programs share the same authority.
11
11
 
@@ -1,6 +1,6 @@
1
1
  /** Semantic Hub Tools and operation results at the MCP boundary. */
2
2
  import { z } from "zod";
3
- import { Id, INTERFACE_NAME, Level, } from "../../domain/model/index.js";
3
+ import { Id, INTERFACE_NAME } from "../../domain/model/index.js";
4
4
  const TOOL_META = "agentorg/tool";
5
5
  const ToolMetadata = z.strictObject({
6
6
  id: Id,
@@ -8,7 +8,6 @@ const ToolMetadata = z.strictObject({
8
8
  interface: z.string().regex(INTERFACE_NAME),
9
9
  one_way: z.boolean(),
10
10
  long_running: z.boolean(),
11
- level: Level.optional(),
12
11
  });
13
12
  /** Flatten explicit Hub Tools for MCP while retaining their identity and local names. */
14
13
  export function offeredToolsOf(catalog) {
@@ -30,7 +29,6 @@ export function offeredToolsOf(catalog) {
30
29
  interface: name,
31
30
  one_way,
32
31
  long_running,
33
- ...(offer.level === undefined ? {} : { level: offer.level }),
34
32
  },
35
33
  },
36
34
  };
@@ -64,7 +62,6 @@ export function catalogOf(tools) {
64
62
  long_running: meta.long_running,
65
63
  },
66
64
  ...(readOnly === undefined ? {} : { read_only: readOnly }),
67
- ...(meta.level === undefined ? {} : { level: meta.level }),
68
65
  });
69
66
  catalog.set(meta.id, group);
70
67
  calls.add(tool.name);
@@ -7,7 +7,7 @@ const note = (text) => process.stderr.write(`agentorg: ${text}\n`);
7
7
  async function asActor(run) {
8
8
  const identity = readIdentity();
9
9
  if (!identity) {
10
- throw new Error(`no identity: set AGENTORG_ACTOR_ID and AGENTORG_CREDENTIAL, or run \`agentorg-server\`, which writes the root's credential to ${rootCredentialPath()}`);
10
+ throw new Error(`no identity: set AGENTORG_ACTOR_ID and AGENTORG_CREDENTIAL, or run \`agentorg-server\`, which writes the person's credential to ${rootCredentialPath()}`);
11
11
  }
12
12
  const url = coreUrl();
13
13
  const client = await connectClient({ url, ...identity, name: "agentorg-cli" }).catch((error) => {
@@ -14,7 +14,7 @@ const usage = () => [
14
14
  " call <name> --json <json> Invoke any permitted interface; print its complete answer.",
15
15
  ...builtinLines(),
16
16
  "",
17
- "Set AGENTORG_ACTOR_ID with AGENTORG_CREDENTIAL, else use the root's local identity.",
17
+ "Set AGENTORG_ACTOR_ID with AGENTORG_CREDENTIAL, else use the person's local identity.",
18
18
  "agentorg <operation> --help shows its flags.",
19
19
  ].join("\n");
20
20
  export async function main(argv) {
@@ -5,22 +5,20 @@
5
5
  * never the credential. Workspace record authority remains with the Hub and package clients.
6
6
  */
7
7
  import { type PresentationOptions, type Presented } from "../../actor/index.ts";
8
- import { type Answer, type InterfaceDescriptor, type Level, type ToolDescriptor } from "../../domain/model/index.ts";
8
+ import { type Answer, type InterfaceDescriptor, type ToolDescriptor } from "../../domain/model/index.ts";
9
9
  export declare const ATTACH: InterfaceDescriptor;
10
10
  /** What the session's client may show its model about the agent actor's tools as a whole. */
11
- export declare const INSTRUCTIONS = "These tools make this session a position in an AgentOrg organization: a responsibility with a manager, under the user. Attach before any other action, with the actor id the brief names, or with a name and purpose when the user started the session with no position named. Then use interfaces to list the Hub interfaces this session presents, interfaces {name} to read one's schemas, and call with {name, input} to invoke one. Logical names such as work_update and attention are operations through call. How to work in a position is the agentorg skill; without it, read https://github.com/uniac-ai/AgentOrg/blob/main/skills/agentorg/SKILL.md.";
11
+ export declare const INSTRUCTIONS = "These tools make this session an Actor in an AgentOrg organization: a responsibility on its one flat level, working for the user. Attach before any other action, with the actor id the brief names, or with a name and purpose when the user started the session with no position named. Then use interfaces to list the Hub's interfaces, interfaces {name} to read one's schemas, and call with {name, input} to invoke one. Logical names such as work_update and attention are operations through call. How to work as an Actor is the agentorg skill; without it, read https://github.com/uniac-ai/AgentOrg/blob/main/skills/agentorg/SKILL.md.";
12
12
  export interface AgentOptions {
13
13
  coreUrl: string;
14
14
  /** The client session this agent serves, when the client names one; it remembers the position. */
15
15
  session: string | undefined;
16
16
  /** A client that identifies its session on each call instead of at process startup. */
17
17
  client?: string;
18
- /** The organization level whose interfaces `interfaces` presents; without one, all of them. */
19
- level?: Level;
20
18
  }
21
19
  export declare class Agent implements Presented {
22
20
  #private;
23
- readonly instructions = "These tools make this session a position in an AgentOrg organization: a responsibility with a manager, under the user. Attach before any other action, with the actor id the brief names, or with a name and purpose when the user started the session with no position named. Then use interfaces to list the Hub interfaces this session presents, interfaces {name} to read one's schemas, and call with {name, input} to invoke one. Logical names such as work_update and attention are operations through call. How to work in a position is the agentorg skill; without it, read https://github.com/uniac-ai/AgentOrg/blob/main/skills/agentorg/SKILL.md.";
21
+ readonly instructions = "These tools make this session an Actor in an AgentOrg organization: a responsibility on its one flat level, working for the user. Attach before any other action, with the actor id the brief names, or with a name and purpose when the user started the session with no position named. Then use interfaces to list the Hub's interfaces, interfaces {name} to read one's schemas, and call with {name, input} to invoke one. Logical names such as work_update and attention are operations through call. How to work as an Actor is the agentorg skill; without it, read https://github.com/uniac-ai/AgentOrg/blob/main/skills/agentorg/SKILL.md.";
24
22
  constructor(options: AgentOptions);
25
23
  /** Connect the position this session filled before, if it did; retried until the core answers. */
26
24
  resume(): Promise<void>;
@@ -9,22 +9,21 @@ import { z } from "zod";
9
9
  import { connectClient, } from "../../actor/index.js";
10
10
  import { Handle, Id, objectSchema, Text, } from "../../domain/model/index.js";
11
11
  import { credentials, readPrivate, rootActorPath, rootCredentialPath } from "../../home.js";
12
- import { presented } from "./levels.js";
13
12
  import { sessionName, sessions } from "./sessions.js";
14
13
  const AttachRequest = z.strictObject({
15
14
  actor: Id.optional().describe("The id of the position your brief names."),
16
- name: Handle.optional().describe("Only when the user appointed you directly, with no position named: your handle under the user."),
15
+ name: Handle.optional().describe("Only when the user appointed you directly, with no position named: your handle."),
17
16
  purpose: Text.optional().describe("With name: what your position is for."),
18
17
  });
19
18
  const Attached = z.strictObject({
20
19
  actor: Id.describe("The position you now fill."),
21
- created: z.boolean().describe("True when attaching created it, under the user."),
20
+ created: z.boolean().describe("True when attaching created it."),
22
21
  });
23
22
  export const ATTACH = {
24
23
  name: "attach",
25
24
  description: `Fill your position in the organization before listing or calling Hub Tools. A resumed session can acknowledge its same actor; an attached session cannot change actors.
26
25
 
27
- Give actor, the id your brief names. A session the user started with an appointment, naming no position, gives name and purpose instead, once: that creates its position directly under the user. Then team shows your position, your manager and your reports.`,
26
+ Give actor, the id your brief names. A session the user started with an appointment, naming no position, gives name and purpose instead, once: that creates its Actor, beside every other. Then team shows every open Actor, you among them.`,
28
27
  input: objectSchema(AttachRequest, "input"),
29
28
  output: objectSchema(Attached, "output"),
30
29
  one_way: false,
@@ -39,7 +38,7 @@ const InterfacesRequest = z.strictObject({
39
38
  });
40
39
  const INTERFACES = {
41
40
  name: "interfaces",
42
- description: "List the Hub interfaces this session presents, each with its call alias and a one-line summary. Give name to read one interface's description and input/output schemas before calling an operation whose contract you have not read.",
41
+ description: "List the Hub's interfaces, each with its call alias and a one-line summary. Give name to read one interface's description and input/output schemas before calling an operation whose contract you have not read.",
43
42
  input: objectSchema(InterfacesRequest, "input"),
44
43
  one_way: false,
45
44
  long_running: false,
@@ -52,7 +51,7 @@ const CALL = {
52
51
  long_running: false,
53
52
  };
54
53
  /** What the session's client may show its model about the agent actor's tools as a whole. */
55
- export const INSTRUCTIONS = `These tools make this session a position in an AgentOrg organization: a responsibility with a manager, under the user. Attach before any other action, with the actor id the brief names, or with a name and purpose when the user started the session with no position named. Then use interfaces to list the Hub interfaces this session presents, interfaces {name} to read one's schemas, and call with {name, input} to invoke one. Logical names such as work_update and attention are operations through call. How to work in a position is the agentorg skill; without it, read https://github.com/uniac-ai/AgentOrg/blob/main/skills/agentorg/SKILL.md.`;
54
+ export const INSTRUCTIONS = `These tools make this session an Actor in an AgentOrg organization: a responsibility on its one flat level, working for the user. Attach before any other action, with the actor id the brief names, or with a name and purpose when the user started the session with no position named. Then use interfaces to list the Hub's interfaces, interfaces {name} to read one's schemas, and call with {name, input} to invoke one. Logical names such as work_update and attention are operations through call. How to work as an Actor is the agentorg skill; without it, read https://github.com/uniac-ai/AgentOrg/blob/main/skills/agentorg/SKILL.md.`;
56
55
  const refused = (code, message) => ({ state: "refused", code, message });
57
56
  export class Agent {
58
57
  instructions = INSTRUCTIONS;
@@ -67,12 +66,6 @@ export class Agent {
67
66
  this.#session = options.session;
68
67
  if (this.#session !== undefined)
69
68
  this.#filled = sessions.position(this.#session);
70
- this.#present();
71
- }
72
- /** Record the level this server presents beside a filled position, for the session's waiter. */
73
- #present() {
74
- if (this.#session !== undefined && this.#filled !== undefined)
75
- sessions.present(this.#session, this.#options.level);
76
69
  }
77
70
  /** Connect the position this session filled before, if it did; retried until the core answers. */
78
71
  async resume() {
@@ -168,14 +161,12 @@ export class Agent {
168
161
  catch {
169
162
  return refused("unavailable", "the Hub did not list available Tools");
170
163
  }
171
- const level = this.#options.level;
172
- const offers = presented(tools, level);
164
+ const offers = tools.flatMap((tool) => tool.interfaces);
173
165
  if (name === undefined) {
174
166
  const summaryOf = (description = "") => description.split("\n\n")[0] ?? "";
175
167
  return {
176
168
  state: "done",
177
169
  value: {
178
- ...(level === undefined ? {} : { level }),
179
170
  interfaces: offers.map((offer) => ({
180
171
  name: offer.call,
181
172
  summary: summaryOf(offer.interface.description),
@@ -185,9 +176,7 @@ export class Agent {
185
176
  }
186
177
  const offer = offers.find((each) => each.call === name);
187
178
  if (offer === undefined)
188
- return refused("not_found", presented(tools, undefined).some((each) => each.call === name)
189
- ? `${name} is not presented at the ${level} level`
190
- : `there is no Hub interface ${name}`);
179
+ return refused("not_found", `there is no Hub interface ${name}`);
191
180
  const { description, input, output } = offer.interface;
192
181
  return {
193
182
  state: "done",
@@ -216,7 +205,6 @@ export class Agent {
216
205
  }
217
206
  this.#session = session;
218
207
  this.#filled = sessions.position(session);
219
- this.#present();
220
208
  const actor = this.#filled;
221
209
  const credential = actor === undefined ? undefined : credentials.read(actor);
222
210
  if (actor !== undefined && credential !== undefined) {
@@ -238,7 +226,7 @@ export class Agent {
238
226
  }
239
227
  let actor = request.actor;
240
228
  if (actor === undefined) {
241
- const created = await this.#createUnderRoot(request.name, request.purpose);
229
+ const created = await this.#createWithPerson(request.name, request.purpose);
242
230
  if (created.state !== "done")
243
231
  return created;
244
232
  actor = created.value;
@@ -257,7 +245,6 @@ export class Agent {
257
245
  this.#filled = actor;
258
246
  if (this.#session !== undefined) {
259
247
  sessions.fill(this.#session, actor);
260
- this.#present();
261
248
  // Delivery starts from now: what happened before the session attached is not its input.
262
249
  // Without it, the waiter starts from whenever it first reads.
263
250
  const now = await this.#position?.call("attention", {}).catch(() => undefined);
@@ -267,9 +254,9 @@ export class Agent {
267
254
  return { state: "done", value: { actor, created: request.actor === undefined } };
268
255
  }
269
256
  /**
270
- * Create the session's position under the root with the root's credential, used for that only.
257
+ * Create the session's Actor with the person's credential, used for that only.
271
258
  */
272
- async #createUnderRoot(name, purpose) {
259
+ async #createWithPerson(name, purpose) {
273
260
  const file = rootCredentialPath();
274
261
  if (!existsSync(file))
275
262
  return refused("not_found", `no root credential in ${file}`);
@@ -8,5 +8,5 @@
8
8
  export declare function claudeTakesInput(line: string): boolean;
9
9
  /** What a session that fills no position reads before its first turn. */
10
10
  export declare const ATTACH_FIRST = "agentorg: This session can fill a position in an AgentOrg organization. Load the agentorg skill, then attach with `attach` before any other action.";
11
- export declare const MCP_HELP: string;
11
+ export declare const MCP_HELP = "usage: agentorg-mcp [--client claude-code|codex]\n agentorg-mcp context|wait [--client claude-code|codex]\n agentorg-mcp connect <claude-code|codex> [--project <dir>]\n agentorg-mcp disconnect <claude-code|codex> [--project <dir>]\n agentorg-mcp status [--project <dir>]\n\nPresent attach, interfaces and call over stdio, connected to AGENTORG_URL. Listing and invocation require attachment. interfaces lists the Hub interfaces with one-line summaries, and interfaces {name} returns one's schemas; call invokes an interface by its call alias.\nClient hooks: context emits an attachment hint; wait delivers what concerns the attached Actor, read with attention, on stderr with the client's wake status.";
12
12
  export declare function mcpCommand(args: string[]): Promise<number>;
@@ -3,7 +3,6 @@ import { execFileSync } from "node:child_process";
3
3
  import { once } from "node:events";
4
4
  import { parseArgs } from "node:util";
5
5
  import { presentOverStdio } from "../../actor/index.js";
6
- import { Level } from "../../domain/model/index.js";
7
6
  import { coreUrl } from "../../network/index.js";
8
7
  import { help } from "../../runtime/command.js";
9
8
  import { Agent } from "./agent.js";
@@ -75,7 +74,6 @@ function client(args) {
75
74
  args,
76
75
  options: {
77
76
  client: { type: "string", default: "claude-code" },
78
- level: { type: "string" },
79
77
  },
80
78
  allowPositionals: true,
81
79
  strict: true,
@@ -85,10 +83,7 @@ function client(args) {
85
83
  if (found === undefined) {
86
84
  throw new Error(`unknown client ${name}; known: ${Object.keys(CLIENTS).join(", ")}`);
87
85
  }
88
- const level = values.level === undefined ? undefined : Level.safeParse(values.level);
89
- if (level?.success === false)
90
- throw new Error(`unknown level ${values.level}; known: ${Level.options.join(", ")}`);
91
- return { name, client: found, level: level?.data, rest: positionals };
86
+ return { name, client: found, rest: positionals };
92
87
  }
93
88
  async function text(stream) {
94
89
  let read = "";
@@ -99,13 +94,13 @@ async function text(stream) {
99
94
  const sessionOf = (name, client, input) => sessionName(name, client.session(input));
100
95
  /** What a session that fills no position reads before its first turn. */
101
96
  export const ATTACH_FIRST = "agentorg: This session can fill a position in an AgentOrg organization. Load the agentorg skill, then attach with `attach` before any other action.";
102
- export const MCP_HELP = `usage: agentorg-mcp [--client claude-code|codex] [--level ${Level.options.join("|")}]
97
+ export const MCP_HELP = `usage: agentorg-mcp [--client claude-code|codex]
103
98
  agentorg-mcp context|wait [--client claude-code|codex]
104
- agentorg-mcp connect <claude-code|codex> [--project <dir>] [--level <level>]
99
+ agentorg-mcp connect <claude-code|codex> [--project <dir>]
105
100
  agentorg-mcp disconnect <claude-code|codex> [--project <dir>]
106
101
  agentorg-mcp status [--project <dir>]
107
102
 
108
- Present attach, interfaces and call over stdio, connected to AGENTORG_URL. Listing and invocation require attachment. interfaces lists the Hub interfaces of the chosen level (without one, the whole catalog) with one-line summaries, and interfaces {name} returns one's schemas; call invokes an interface by its call alias.
103
+ Present attach, interfaces and call over stdio, connected to AGENTORG_URL. Listing and invocation require attachment. interfaces lists the Hub interfaces with one-line summaries, and interfaces {name} returns one's schemas; call invokes an interface by its call alias.
109
104
  Client hooks: context emits an attachment hint; wait delivers what concerns the attached Actor, read with attention, on stderr with the client's wake status.`;
110
105
  export async function mcpCommand(args) {
111
106
  const command = args[0];
@@ -117,7 +112,7 @@ export async function mcpCommand(args) {
117
112
  }
118
113
  if (asked)
119
114
  return help(MCP_HELP);
120
- const { name, client: chosen, level, rest } = client(args);
115
+ const { name, client: chosen, rest } = client(args);
121
116
  const input = name === "codex" && ["context", "wait"].includes(rest[0] ?? "")
122
117
  ? await text(process.stdin)
123
118
  : undefined;
@@ -145,7 +140,6 @@ export async function mcpCommand(args) {
145
140
  const agent = new Agent({
146
141
  coreUrl: coreUrl(),
147
142
  session,
148
- ...(level === undefined ? {} : { level }),
149
143
  ...(name === "codex" ? { client: name } : {}),
150
144
  });
151
145
  const server = await presentOverStdio(agent);
@@ -4,10 +4,9 @@
4
4
  * installed command whatever the client's `PATH`. `connect` writes only entries it can find again:
5
5
  * connecting again replaces them, and `disconnect` removes them and nothing of the user's.
6
6
  */
7
- import type { Level } from "../../domain/model/index.ts";
8
7
  export interface Client {
9
8
  /** Write the client's configuration and the skill link; return the paths written. */
10
- connect(project: string, launcher: string, level?: Level): string[];
9
+ connect(project: string, launcher: string): string[];
11
10
  /** Remove them; return the paths changed. */
12
11
  disconnect(project: string): string[];
13
12
  /** Undefined when the project isn't connected, else what is wrong with its connection. */
@@ -72,11 +72,7 @@ function skillProblems(folder) {
72
72
  return [];
73
73
  }
74
74
  const shellWord = (text) => `'${text.replaceAll("'", `'\\''`)}'`;
75
- const agentArgs = (client, level) => [
76
- "--client",
77
- client,
78
- ...(level === undefined ? [] : ["--level", level]),
79
- ];
75
+ const agentArgs = (client) => ["--client", client];
80
76
  // Claude Code: the server in `.mcp.json`, approved and hooked in `.claude/settings.local.json`, the
81
77
  // user's own settings for the project, and the skill in `.claude/skills/`.
82
78
  const HOOK_COMMAND = /\/agentorg-mcp' (context|prompt|wait) --client (claude-code|codex)$/;
@@ -168,14 +164,14 @@ function claudeServer(path) {
168
164
  return org;
169
165
  }
170
166
  const claudeCode = {
171
- connect(project, launcher, level) {
167
+ connect(project, launcher) {
172
168
  const files = claudeFiles(project);
173
169
  claudeServer(files.servers);
174
170
  const config = readJson(files.servers);
175
171
  const servers = isObject(config.mcpServers) ? config.mcpServers : {};
176
172
  config.mcpServers = {
177
173
  ...servers,
178
- org: { command: launcher, args: agentArgs("claude-code", level) },
174
+ org: { command: launcher, args: agentArgs("claude-code") },
179
175
  };
180
176
  writeJson(files.servers, config);
181
177
  const settings = readJson(files.settings);
@@ -278,14 +274,14 @@ const codexFiles = (project) => ({
278
274
  skills: join(project, ".agents", "skills"),
279
275
  });
280
276
  const codex = {
281
- connect(project, launcher, level) {
277
+ connect(project, launcher) {
282
278
  const files = codexFiles(project);
283
279
  const config = codexConfig(files.config);
284
280
  const hooks = readJson(files.hooks);
285
281
  withOurHooks(hooks, "codex", launcher);
286
282
  const settings = {
287
283
  command: JSON.stringify(launcher),
288
- args: JSON.stringify(agentArgs("codex", level)),
284
+ args: JSON.stringify(agentArgs("codex")),
289
285
  };
290
286
  let text;
291
287
  if (config.table === undefined) {
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  * Which client session fills which position, kept in the home's `sessions/<session>/` so that a
3
- * resumed session fills it again. `position` holds the Actor ID, `level` the level its server
4
- * presents, `waiter` the current waiter PID, and `inbox` the `attention` position the session has
3
+ * resumed session fills it again. `position` holds the Actor ID, `waiter` the current waiter PID, and `inbox` the `attention` position the session has
5
4
  * been given everything before. This private bookkeeping establishes neither public
6
5
  * acknowledgements nor user input.
7
6
  */
@@ -10,9 +9,6 @@ export declare function sessionName(client: string, id: string | undefined): str
10
9
  export declare const sessions: {
11
10
  position: (session: string) => string | undefined;
12
11
  fill: (session: string, actor: string) => void;
13
- /** The level the session's server presents, which the waiter frames for; none is every tool. */
14
- level: (session: string) => string | undefined;
15
- present(session: string, level: string | undefined): void;
16
12
  /** Forget the session, as when its position closed. */
17
13
  forget: (session: string) => void;
18
14
  waiter: (session: string) => number;
@@ -1,7 +1,6 @@
1
1
  /**
2
2
  * Which client session fills which position, kept in the home's `sessions/<session>/` so that a
3
- * resumed session fills it again. `position` holds the Actor ID, `level` the level its server
4
- * presents, `waiter` the current waiter PID, and `inbox` the `attention` position the session has
3
+ * resumed session fills it again. `position` holds the Actor ID, `waiter` the current waiter PID, and `inbox` the `attention` position the session has
5
4
  * been given everything before. This private bookkeeping establishes neither public
6
5
  * acknowledgements nor user input.
7
6
  */
@@ -44,14 +43,6 @@ function replace(session, entry, value) {
44
43
  export const sessions = {
45
44
  position: (session) => read(session, "position"),
46
45
  fill: (session, actor) => write(session, "position", actor),
47
- /** The level the session's server presents, which the waiter frames for; none is every tool. */
48
- level: (session) => read(session, "level"),
49
- present(session, level) {
50
- if (level !== undefined)
51
- replace(session, "level", level);
52
- else
53
- rmSync(join(directory(session), "level"), { force: true });
54
- },
55
46
  /** Forget the session, as when its position closed. */
56
47
  forget: (session) => rmSync(directory(session), { recursive: true, force: true }),
57
48
  waiter: (session) => Number(read(session, "waiter") ?? 0),
@@ -4,17 +4,16 @@ import { statSync } from "node:fs";
4
4
  import { homedir } from "node:os";
5
5
  import { resolve } from "node:path";
6
6
  import { parseArgs } from "node:util";
7
- import { Level } from "../../domain/model/index.js";
8
7
  import { coreUrl } from "../../network/index.js";
9
8
  import { launcherPath, writeLauncher } from "../../runtime/launcher.js";
10
9
  import { answers, launcherStatus, printReport } from "../../runtime/status.js";
11
10
  import { CLIENTS, clientOf } from "./projects.js";
12
11
  const PROGRAM = "agentorg-mcp";
13
12
  const NAMES = Object.keys(CLIENTS).join("|");
14
- export const CONNECT_HELP = `usage: agentorg-mcp connect <${NAMES}> [--project <dir>] [--level ${Level.options.join("|")}]
13
+ export const CONNECT_HELP = `usage: agentorg-mcp connect <${NAMES}> [--project <dir>]
15
14
  agentorg-mcp disconnect <${NAMES}> [--project <dir>]
16
15
 
17
- connect pins this MCP adapter and Node in <home>/bin/agentorg-mcp, configures the project's org MCP server and hooks, and links the package's agentorg skill. --level chooses the interfaces the server presents; without it, the whole catalog. Claude Code also gets its MCP approval. The project's other entries stay as they are. Codex requires project trust, enabled hooks (features.hooks), and review and trust of the hook definitions through /hooks.
16
+ connect pins this MCP adapter and Node in <home>/bin/agentorg-mcp, configures the project's org MCP server and hooks, and links the package's agentorg skill. Claude Code also gets its MCP approval. The project's other entries stay as they are. Codex requires project trust, enabled hooks (features.hooks), and review and trust of the hook definitions through /hooks.
18
17
 
19
18
  connect checks through the launcher with a bare PATH. disconnect removes only this adapter's entries.`;
20
19
  export const STATUS_HELP = `usage: agentorg-mcp status [--project <dir>]
@@ -29,7 +28,7 @@ const projectOf = (path) => {
29
28
  export async function setupCommand(command, args) {
30
29
  const { values, positionals } = parseArgs({
31
30
  args,
32
- options: { project: { type: "string" }, level: { type: "string" } },
31
+ options: { project: { type: "string" } },
33
32
  allowPositionals: true,
34
33
  strict: true,
35
34
  });
@@ -63,11 +62,8 @@ export async function setupCommand(command, args) {
63
62
  : `${name} was not connected\n`);
64
63
  return 0;
65
64
  }
66
- const level = values.level === undefined ? undefined : Level.safeParse(values.level);
67
- if (level?.success === false)
68
- throw new Error(`unknown level ${values.level}; known: ${Level.options.join(", ")}`);
69
65
  const launcher = writeLauncher(PROGRAM);
70
- const written = client.connect(project, launcher, level?.data);
66
+ const written = client.connect(project, launcher);
71
67
  process.stdout.write(`connected ${name} in ${project}:\n${written.map((path) => ` wrote ${path}`).join("\n")}\nchecking through the launcher, with only /usr/bin and /bin on PATH:\n`);
72
68
  if (name === "codex") {
73
69
  process.stdout.write("Codex: trust this project's configuration, enable features.hooks, and review and trust AgentOrg's definitions through /hooks. These hooks do not wake an idle turn.\n");
@@ -25,8 +25,6 @@ export type Delivery = Item & {
25
25
  };
26
26
  interface Here {
27
27
  self: z.output<typeof Position>;
28
- /** The call aliases the session's server presents; a frame names work_answer only if presented. */
29
- presented: ReadonlySet<string>;
30
28
  }
31
29
  export declare function waitForNews(options: WaitOptions): Promise<boolean>;
32
30
  export declare function describe(items: Delivery[], here: Here): string;
@@ -1,7 +1,6 @@
1
1
  import { connectClient } from "../../actor/index.js";
2
- import { Level, MAX_WAIT_SECONDS } from "../../domain/model/index.js";
2
+ import { MAX_WAIT_SECONDS } from "../../domain/model/index.js";
3
3
  import { credentials } from "../../home.js";
4
- import { presented } from "./levels.js";
5
4
  import { sessions } from "./sessions.js";
6
5
  const value = (answer) => {
7
6
  if (answer.state === "done")
@@ -83,8 +82,8 @@ export async function waitForNews(options) {
83
82
  void connected.close().catch(() => { });
84
83
  }, 100);
85
84
  watch.unref();
86
- const team = await call(client, "team", { depth: 0 });
87
- const self = team.positions[0];
85
+ const team = await call(client, "team", {});
86
+ const self = team.positions.find((position) => position.id === actorID);
88
87
  if (!self)
89
88
  throw new Error("the Hub named no position");
90
89
  while (current()) {
@@ -102,11 +101,7 @@ export async function waitForNews(options) {
102
101
  items.push(await delivery(client, actorID, item));
103
102
  if (!current())
104
103
  return false;
105
- const level = Level.safeParse(sessions.level(options.session)).data;
106
- const offers = presented(await client.available(), level);
107
- if (!current())
108
- return false;
109
- options.write(describe(items, { self, presented: new Set(offers.map((o) => o.call)) }));
104
+ options.write(describe(items, { self }));
110
105
  sessions.advanceInbox(options.session, read.next);
111
106
  return true;
112
107
  }
@@ -126,11 +121,9 @@ export async function waitForNews(options) {
126
121
  return false;
127
122
  }
128
123
  const quoted = (text) => `"${text}"`;
129
- /** What one item says to the session, with what to do about it, in tools its level presents. */
124
+ /** What one item says to the session, with what to do about it. */
130
125
  function frame(item, here) {
131
- const from = `${item.from.name}${item.from.actorID === here.self.manager ? ", your manager," : ""}`;
132
- // Answering and raising name work_answer, which the session's level may not present.
133
- const answering = here.presented.has("work_answer");
126
+ const from = item.from.name;
134
127
  switch (item.kind) {
135
128
  case "answer": {
136
129
  const response = item.ask?.responses[item.from.actorID];
@@ -146,9 +139,7 @@ function frame(item, here) {
146
139
  return `${from} answered your ask ${quoted(item.title)} (${item.recordID}): ${answers}.${note} Apply it${work}. The ask records the answer; ${item.ask?.status === "open" ? "it collects more until you close it" : "it is resolved"}.`;
147
140
  }
148
141
  case "ask":
149
- return `${from} routes you the ask ${quoted(item.title)} (${item.recordID}). Read it with work_get {askID: "${item.recordID}"}${answering ? ", then answer it with work_answer {askID, answers, note?}, or raise it one manager up with work_answer {askID, raise: true}" : ""}.`;
150
- case "raised":
151
- return `${from} raised your ask ${quoted(item.title)} (${item.recordID}) to its manager; it stays open until someone answers it. Keep working on what doesn't depend on it.`;
142
+ return `${from} routes you the ask ${quoted(item.title)} (${item.recordID}). Read it with work_get {askID: "${item.recordID}"}, then answer it with work_answer {askID, answers, note?}.`;
152
143
  case "updated":
153
144
  return item.work?.status === "cancelled"
154
145
  ? `${from} cancelled your Work ${quoted(item.title)} (${item.recordID}); its open asks are cancelled. Stop working on it.`
@@ -157,9 +148,7 @@ function frame(item, here) {
157
148
  return `${from} gave you Work ${quoted(item.title)} (${item.recordID}). Read it with work_get; set it active with work_update when you start.`;
158
149
  case "review_due": {
159
150
  const submission = item.work?.submission;
160
- const answer = answering
161
- ? `, then answer it with work_answer {askID: ${submission ? `"${submission.submissionID}"` : "<its submissionID>"}, answers: {verdict: "accepted" or "changes_requested"}, note?}; requesting changes needs the note`
162
- : "";
151
+ const answer = `, then answer it with work_answer {askID: ${submission ? `"${submission.submissionID}"` : "<its submissionID>"}, answers: {verdict: "accepted" or "changes_requested"}, note?}; requesting changes needs the note`;
163
152
  // A submission a close re-routes comes from the Actor that closed, not from its submitter.
164
153
  return submission && submission.ownerID !== item.from.actorID
165
154
  ? `${from} closed the Actor the submission of ${quoted(item.title)} (${item.recordID}) waited on; it now waits for your answer. Read the submission with work_get${answer}.`
@@ -175,7 +164,7 @@ function frame(item, here) {
175
164
  }
176
165
  export function describe(items, here) {
177
166
  return [
178
- `AgentOrg, for ${here.self.path || here.self.name} (${here.self.id}). These come through the Hub from other Actors, not from the user typing in this session. An answer is an ordinary Actor record; a native approval requires its client's validated binding.`,
167
+ `AgentOrg, for ${here.self.name} (${here.self.id}). These come through the Hub from other Actors, not from the user typing in this session. An answer is an ordinary Actor record; a native approval requires its client's validated binding.`,
179
168
  ...items.map((item) => frame(item, here)),
180
169
  ].join("\n\n");
181
170
  }
@@ -5,17 +5,13 @@ export { ACTORS as definition } from "./model/index.js";
5
5
  export function actors(registry, connections, execution) {
6
6
  function view(actor) {
7
7
  const { credential_hash: _, ...identity } = actor;
8
- return {
9
- ...identity,
10
- path: registry.path(actor),
11
- online: connections.connected(actor.id),
12
- };
8
+ return { ...identity, online: connections.connected(actor.id) };
13
9
  }
14
10
  return {
15
11
  view,
16
12
  tool: bindTool(ACTORS, {
17
- actor_create: async (actor, request) => {
18
- const { actor: created, credential } = await registry.create(actor.id, request.name, request.purpose);
13
+ actor_create: async (_actor, request) => {
14
+ const { actor: created, credential } = await registry.create(request.name, request.purpose);
19
15
  const outcome = request.execution === undefined
20
16
  ? undefined
21
17
  : await execution.create({
@@ -1,12 +1,13 @@
1
1
  /**
2
2
  * What concerns an Actor, read from the audited writes after its position, by the next mover.
3
- * On its records: Work given to it or changed by its requester, an answer to its
4
- * submission, an answer to its ask or the ask's raise, and a message to it. Routed to it, or to a
5
- * closed Actor it stands in for: an ask from a report or raised to it while the ask is open and
6
- * with it, and a submission of Work it requested while the submission waits. Closing an Actor gives
7
- * its stand-in an ask for each open ask the close re-routes and a review_due for each waiting
8
- * submission, from the Actor that closed it; a stand-in that closed it gets none, as its own
9
- * write. A read that finds nothing waits for the next audited write, up to `wait` seconds.
3
+ * On its records: Work given to it or changed by its requester, an answer to its submission, an
4
+ * answer to its ask, and a message to it. Routed to it: an ask on Work it requested while the ask
5
+ * is open and still routed to it, and a submission of Work it requested while the submission
6
+ * waits. The person also gets the asks on Work their asker requested itself or on no Work, and
7
+ * stands in for closed Actors: closing one gives it an ask for each open ask the close re-routes
8
+ * and a review_due for each waiting submission, from the Actor that closed it, or none when the
9
+ * person closed it, as its own write. A read that finds nothing waits for the next audited write,
10
+ * up to `wait` seconds.
10
11
  */
11
12
  import type { Audit } from "./audit.ts";
12
13
  import type { Registry } from "./registry.ts";