super-dsh 0.1.3 → 0.1.4

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 (115) hide show
  1. package/README.md +9 -8
  2. package/agent-agy/cordis.patch.yml +8 -4
  3. package/agent-agy/dist/agent-preset-agy.d.ts +23 -43
  4. package/agent-agy/dist/agent-preset-agy.js +29 -166
  5. package/agent-agy/dist/agent.d.ts +2 -1
  6. package/agent-agy/dist/agent.js +3 -2
  7. package/agent-agy/dist/agy-sessions.d.ts +2 -1
  8. package/agent-agy/dist/agy-sessions.js +2 -11
  9. package/agent-agy/dist/index.js +13 -12
  10. package/agent-agy/dist/world-plugin.d.ts +2 -1
  11. package/agent-agy/dist/world-plugin.js +16 -21
  12. package/agent-agy/package.json +6 -6
  13. package/agent-claude/cordis.patch.yml +8 -4
  14. package/agent-claude/dist/agent-preset-claude.js +29 -166
  15. package/agent-claude/dist/agent.js +10 -10
  16. package/agent-claude/dist/claude-client.js +22 -3
  17. package/agent-claude/dist/claude-home.js +0 -8
  18. package/agent-claude/dist/index.js +12 -15
  19. package/agent-claude/dist/session-map.js +2 -5
  20. package/agent-claude/dist/world-plugin.js +3 -3
  21. package/agent-claude/package.json +9 -9
  22. package/agent-codex/README.md +8 -8
  23. package/agent-codex/cordis.patch.yml +9 -5
  24. package/agent-codex/dist/agent-preset-codex.js +29 -168
  25. package/agent-codex/dist/agent.js +17 -12
  26. package/agent-codex/dist/codex-store.js +0 -9
  27. package/agent-codex/dist/index.js +13 -16
  28. package/agent-codex/dist/session-map.js +2 -5
  29. package/agent-codex/dist/world-plugin.js +15 -20
  30. package/agent-codex/package.json +14 -11
  31. package/agent-hermes/README.md +9 -8
  32. package/agent-hermes/cordis.patch.yml +8 -4
  33. package/agent-hermes/dist/agent-preset-hermes.js +29 -168
  34. package/agent-hermes/dist/agent.js +33 -19
  35. package/agent-hermes/dist/hermes-client.js +5 -5
  36. package/agent-hermes/dist/hermes-store.js +2 -11
  37. package/agent-hermes/dist/index.js +13 -12
  38. package/agent-hermes/dist/world-plugin.js +16 -21
  39. package/agent-hermes/package.json +14 -11
  40. package/agent-omp/README.md +2 -2
  41. package/agent-omp/cordis.patch.yml +12 -7
  42. package/agent-omp/dist/agent-preset-omp.js +30 -169
  43. package/agent-omp/dist/agent.js +13 -5
  44. package/agent-omp/dist/index.js +12 -22
  45. package/agent-omp/dist/mobile/gesture.js +2 -2
  46. package/agent-omp/dist/mobile/zoom-guard.js +4 -4
  47. package/agent-omp/dist/mobile-boot.js +2 -2
  48. package/agent-omp/dist/omp-cli.js +1 -1
  49. package/agent-omp/dist/omp-disk-discovery.js +1 -1
  50. package/agent-omp/dist/protocol.js +1 -1
  51. package/agent-omp/dist/sidecar-client.js +1 -1
  52. package/agent-omp/dist/world-plugin.js +22 -19
  53. package/agent-omp/package.json +18 -14
  54. package/agent-omp/sidecar/main.ts +2 -2
  55. package/agent-pi/README.md +5 -5
  56. package/agent-pi/cordis.patch.yml +8 -4
  57. package/agent-pi/dist/agent-preset-pi.js +29 -166
  58. package/agent-pi/dist/agent.js +18 -12
  59. package/agent-pi/dist/index.js +14 -16
  60. package/agent-pi/dist/pi-home.js +2 -12
  61. package/agent-pi/dist/world-plugin.js +16 -21
  62. package/agent-pi/package.json +14 -11
  63. package/cordis.patch.yml +31 -21
  64. package/package.json +30 -38
  65. package/{agent-hub → superd-hub}/cordis.patch.yml +3 -3
  66. package/{agent-hub → superd-hub}/dist/carrier.d.ts +9 -3
  67. package/{agent-hub → superd-hub}/dist/carrier.js +29 -3
  68. package/{agent-hub → superd-hub}/dist/gateway.d.ts +2 -2
  69. package/{agent-hub → superd-hub}/dist/gateway.js +1 -1
  70. package/{agent-hub → superd-hub}/dist/index.d.ts +5 -3
  71. package/{agent-hub → superd-hub}/dist/index.js +5 -3
  72. package/{agent-hub → superd-hub}/dist/roster.d.ts +2 -2
  73. package/{agent-hub → superd-hub}/dist/rpc.js +1 -1
  74. package/{agent-hub → superd-hub}/dist/spawn-world.d.ts +27 -6
  75. package/superd-hub/dist/spawn-world.js +277 -0
  76. package/superd-hub/dist/system-head.d.ts +69 -0
  77. package/superd-hub/dist/system-head.js +194 -0
  78. package/superd-hub/dist/web-trust.d.ts +112 -0
  79. package/superd-hub/dist/web-trust.js +126 -0
  80. package/{agent-hub → superd-hub}/dist/world-entry.d.ts +2 -2
  81. package/{agent-hub → superd-hub}/dist/world-entry.js +4 -4
  82. package/{agent-hub → superd-hub}/dist/world-host.d.ts +1 -1
  83. package/{agent-hub → superd-hub}/dist/world-join.d.ts +2 -1
  84. package/{agent-hub → superd-hub}/dist/world-join.js +16 -21
  85. package/{agent-hub → superd-hub}/dist/world-mount.d.ts +14 -6
  86. package/{agent-hub → superd-hub}/dist/world-mount.js +28 -7
  87. package/{agent-hub → superd-hub}/dist/world-mux.d.ts +21 -6
  88. package/superd-hub/dist/world-mux.js +392 -0
  89. package/{agent-hub → superd-hub}/dist/world-provision.d.ts +20 -4
  90. package/superd-hub/dist/world-provision.js +196 -0
  91. package/{agent-hub → superd-hub}/dist/world-web-server.js +7 -1
  92. package/{agent-hub → superd-hub}/package.json +9 -16
  93. package/agent-hub/dist/spawn-world.js +0 -72
  94. package/agent-hub/dist/world-mux.js +0 -224
  95. package/agent-hub/dist/world-provision.js +0 -122
  96. package/agent-hub/lib/client/index.js +0 -242
  97. package/client/index.js +0 -242
  98. /package/{agent-hub → superd-hub}/dist/agent-roster.d.ts +0 -0
  99. /package/{agent-hub → superd-hub}/dist/agent-roster.js +0 -0
  100. /package/{agent-hub → superd-hub}/dist/client-shim.d.ts +0 -0
  101. /package/{agent-hub → superd-hub}/dist/client-shim.js +0 -0
  102. /package/{agent-hub → superd-hub}/dist/envelope.d.ts +0 -0
  103. /package/{agent-hub → superd-hub}/dist/envelope.js +0 -0
  104. /package/{agent-hub → superd-hub}/dist/index-pass.d.ts +0 -0
  105. /package/{agent-hub → superd-hub}/dist/index-pass.js +0 -0
  106. /package/{agent-hub → superd-hub}/dist/labels.d.ts +0 -0
  107. /package/{agent-hub → superd-hub}/dist/labels.js +0 -0
  108. /package/{agent-hub → superd-hub}/dist/ownership.d.ts +0 -0
  109. /package/{agent-hub → superd-hub}/dist/ownership.js +0 -0
  110. /package/{agent-hub → superd-hub}/dist/roster.js +0 -0
  111. /package/{agent-hub → superd-hub}/dist/rpc.d.ts +0 -0
  112. /package/{agent-hub → superd-hub}/dist/targets.d.ts +0 -0
  113. /package/{agent-hub → superd-hub}/dist/targets.js +0 -0
  114. /package/{agent-hub → superd-hub}/dist/world-host.js +0 -0
  115. /package/{agent-hub → superd-hub}/dist/world-web-server.d.ts +0 -0
@@ -1,4 +1,4 @@
1
- # @pgmi-builds/agent-adapter-pi (Agent Worlds AW-F)
1
+ # @pgmi-builds/agent-pi (Super D)
2
2
 
3
3
  pi coding agent provider for DeepSeek Harness — an `AgentFactory` dsh plugin that embeds the
4
4
  **pi coding agent** (`@earendil-works/pi-coding-agent@0.84.2`) **in-process via its SDK**
@@ -57,11 +57,11 @@ world form (form B) via the hub.
57
57
 
58
58
  ## Trap: `npm install` materializes the hub link
59
59
 
60
- `dependencies["file:../agent-hub"]` gets materialized by `npm install` as a
61
- **physical copy** under `node_modules/@pgmi-builds/agent-hub` — a second hub
60
+ `dependencies["file:../superd-hub"]` gets materialized by `npm install` as a
61
+ **physical copy** under `node_modules/@pgmi-builds/superd-hub` — a second hub
62
62
  module instance whose rosters/mount-registry are dead. Symptom in world form:
63
63
  the world's virtual webServer never appears (`9 entries did not activate`,
64
64
  everything pending on webServer). After ANY `npm install` in this package,
65
- re-link: `rm -rf node_modules/@pgmi-builds/agent-hub && ln -sfn ../../../agent-hub
66
- node_modules/@pgmi-builds/agent-hub` (codex symlink discipline; same class as
65
+ re-link: `rm -rf node_modules/@pgmi-builds/superd-hub && ln -sfn ../../../superd-hub
66
+ node_modules/@pgmi-builds/superd-hub` (codex symlink discipline; same class as
67
67
  the `@deepseek-ai/*` heal).
@@ -1,4 +1,4 @@
1
- # @pgmi-builds/agent-adapter-pi bundle patch (AW-F SDK line, codex form).
1
+ # @pgmi-builds/agent-pi bundle patch (AW-F SDK line, codex form).
2
2
  # This file is the `dsh.bundle.patch` layer of the adapter package: when the pi
3
3
  # world profile mounts the bundle, the boot merges THIS patch — mount the pi
4
4
  # provider plus disable the native components it replaces.
@@ -18,7 +18,7 @@
18
18
  # the shared ModelRuntime catalog (auth/models-store from ~/.pi).
19
19
  - insert:
20
20
  - id: pi-provider
21
- name: '@pgmi-builds/agent-adapter-pi'
21
+ name: '@pgmi-builds/agent-pi'
22
22
 
23
23
  # pi owns the live agent transcript (its native session JSONL under
24
24
  # ~/.pi/agent/sessions); disable the built-in loop so it does not double-run
@@ -36,8 +36,12 @@
36
36
 
37
37
  # pi is single-mode: the SDK session drives tools itself, so no Dash preset
38
38
  # composition is needed (the provider ships the fixed single-preset roster).
39
- - id: agent-presets
40
- disabled: true
39
+ # 0.1.7: the host AgentPresetRegistry row (renamed `agent-presets` ->
40
+ # `agent-preset-registry`) stays MOUNTED — the adapter registers its one
41
+ # fixed preset into it (src/agent-preset-pi.ts); pin only the default.
42
+ - id: agent-preset-registry
43
+ config:
44
+ default: pi
41
45
 
42
46
  # The upstream jsonl persistence row STAYS MOUNTED: the provider writes the
43
47
  # DSH session log through it (create/open/append/close), so list/read/replay/
@@ -1,169 +1,32 @@
1
- var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
2
- var useValue = arguments.length > 2;
3
- for (var i = 0; i < initializers.length; i++) {
4
- value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
5
- }
6
- return useValue ? value : void 0;
7
- };
8
- var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
9
- function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
10
- var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
11
- var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
12
- var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
13
- var _, done = false;
14
- for (var i = decorators.length - 1; i >= 0; i--) {
15
- var context = {};
16
- for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
17
- for (var p in contextIn.access) context.access[p] = contextIn.access[p];
18
- context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
19
- var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
20
- if (kind === "accessor") {
21
- if (result === void 0) continue;
22
- if (result === null || typeof result !== "object") throw new TypeError("Object expected");
23
- if (_ = accept(result.get)) descriptor.get = _;
24
- if (_ = accept(result.set)) descriptor.set = _;
25
- if (_ = accept(result.init)) initializers.unshift(_);
26
- }
27
- else if (_ = accept(result)) {
28
- if (kind === "field") initializers.unshift(_);
29
- else descriptor[key] = _;
30
- }
31
- }
32
- if (target) Object.defineProperty(target, contextIn.name, descriptor);
33
- done = true;
34
- };
35
- import { Remote, RemoteError, TypertRemoteService } from "@deepseek-ai/dsh-typert-protocol";
36
- const PI_PRESET = Object.freeze({
37
- id: "pi",
38
- trust: "system",
39
- path: "",
1
+ export const PI_PRESET_ID = "pi";
2
+ /** The single fixed Pi preset: mounting it composes nothing. */
3
+ export const PI_PRESET = Object.freeze({
4
+ id: PI_PRESET_ID,
40
5
  name: "Pi",
41
6
  description: "Pi agent via the agent-pi adapter",
7
+ plugins: Object.freeze([]),
42
8
  });
43
- const COMPOSITION_TEXT = [
44
- "# Pi (fixed roster)",
45
- "",
46
- "This deployment runs exactly one agent mode: the Pi provider bridges Dash",
47
- "sessions to a native pi agent over the @earendil-works/pi-coding-agent SDK.",
48
- "There is no per-session plugin composition to configure, so this preset",
49
- "mounts nothing.",
50
- "",
51
- "rows: []",
52
- "",
53
- ].join("\n");
54
- /** The standing scope key every `pi` session reads presenters through. */
55
- const STANDING_KEY = {};
56
- let SinglePiPresetRoster = (() => {
57
- let _classSuper = TypertRemoteService;
58
- let _instanceExtraInitializers = [];
59
- let _remoteList_decorators;
60
- let _remoteRead_decorators;
61
- let _remoteCopy_decorators;
62
- let _remoteDelete_decorators;
63
- let _remoteSelect_decorators;
64
- return class SinglePiPresetRoster extends _classSuper {
65
- static {
66
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
67
- _remoteList_decorators = [Remote("list")];
68
- _remoteRead_decorators = [Remote("read")];
69
- _remoteCopy_decorators = [Remote("copy")];
70
- _remoteDelete_decorators = [Remote("deletePreset")];
71
- _remoteSelect_decorators = [Remote("select")];
72
- __esDecorate(this, null, _remoteList_decorators, { kind: "method", name: "remoteList", static: false, private: false, access: { has: obj => "remoteList" in obj, get: obj => obj.remoteList }, metadata: _metadata }, null, _instanceExtraInitializers);
73
- __esDecorate(this, null, _remoteRead_decorators, { kind: "method", name: "remoteRead", static: false, private: false, access: { has: obj => "remoteRead" in obj, get: obj => obj.remoteRead }, metadata: _metadata }, null, _instanceExtraInitializers);
74
- __esDecorate(this, null, _remoteCopy_decorators, { kind: "method", name: "remoteCopy", static: false, private: false, access: { has: obj => "remoteCopy" in obj, get: obj => obj.remoteCopy }, metadata: _metadata }, null, _instanceExtraInitializers);
75
- __esDecorate(this, null, _remoteDelete_decorators, { kind: "method", name: "remoteDelete", static: false, private: false, access: { has: obj => "remoteDelete" in obj, get: obj => obj.remoteDelete }, metadata: _metadata }, null, _instanceExtraInitializers);
76
- __esDecorate(this, null, _remoteSelect_decorators, { kind: "method", name: "remoteSelect", static: false, private: false, access: { has: obj => "remoteSelect" in obj, get: obj => obj.remoteSelect }, metadata: _metadata }, null, _instanceExtraInitializers);
77
- if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
78
- }
79
- constructor(ctx) {
80
- super(ctx, "agentPresets");
81
- __runInitializers(this, _instanceExtraInitializers);
82
- }
83
- get defaultId() {
84
- return PI_PRESET.id;
85
- }
86
- get roots() {
87
- return [];
88
- }
89
- get authorable() {
90
- return false;
91
- }
92
- async list() {
93
- return [PI_PRESET];
94
- }
95
- async resolve(id) {
96
- if (id === undefined || id === PI_PRESET.id)
97
- return PI_PRESET;
98
- throw new RemoteError("agent-preset/not-found", `agent-presets: preset "${id}" not found (available: pi)`, { agentPreset: id, available: [PI_PRESET.id] });
99
- }
100
- async mount(_agentCtx, id) {
101
- return this.resolve(id);
102
- }
103
- async recompose(_agentCtx, id) {
104
- return this.resolve(id);
105
- }
106
- async read(id) {
107
- await this.resolve(id);
108
- return COMPOSITION_TEXT;
109
- }
110
- // ── Remote RPC surface (alpha: agentPresets routes come from @Remote) ────
111
- async remoteList() {
112
- if (process.env.PI_TRACE === "1")
113
- process.stderr.write("[pi-roster] remoteList INVOKED\n");
114
- return {
115
- presets: [
116
- {
117
- id: PI_PRESET.id,
118
- trust: PI_PRESET.trust,
119
- isDefault: true,
120
- name: PI_PRESET.name,
121
- description: PI_PRESET.description,
122
- },
123
- ],
124
- authorable: this.authorable,
125
- };
126
- }
127
- async remoteRead(agentPreset) {
128
- const preset = await this.resolve(agentPreset);
129
- return {
130
- agentPreset: preset.id,
131
- trust: preset.trust,
132
- content: await this.read(preset.id),
133
- name: preset.name,
134
- description: preset.description,
135
- };
136
- }
137
- async remoteCopy(from, id, name) {
138
- await this.copy(from, id, name);
139
- }
140
- async remoteDelete(id) {
141
- await this.remove(id);
142
- }
143
- /** Fixed roster: one preset, so selecting it is a no-op ack; anything else is unknown. */
144
- async remoteSelect(agent, agentPreset) {
145
- const preset = await this.resolve(agentPreset);
146
- return preset.id;
147
- }
148
- async copy(_from, id, _name) {
149
- throw new RemoteError("agent-preset/read-only", `agent-presets: preset "${id}" cannot be written: the Pi roster is fixed and ships exactly one preset`, { agentPreset: id, reason: "the Pi roster is fixed and ships exactly one preset" });
150
- }
151
- async remove(id) {
152
- throw new RemoteError("agent-preset/read-only", `agent-presets: preset "${id}" cannot be written: the Pi roster is fixed and ships exactly one preset`, { agentPreset: id, reason: "the Pi roster is fixed and ships exactly one preset" });
153
- }
154
- serviceFor(_agent, _name) {
155
- return undefined;
156
- }
157
- composeFrom(_agentCtx, _parentCtx) {
158
- return undefined;
159
- }
160
- composedPreset(_agentCtx) {
161
- return PI_PRESET.id;
162
- }
163
- async standingKeyFor(id) {
164
- await this.resolve(id);
165
- return STANDING_KEY;
166
- }
167
- };
168
- })();
169
- export { SinglePiPresetRoster };
9
+ /**
10
+ * Register the fixed preset into the host `AgentPresetRegistry` once the
11
+ * service is up. Registration failure keeps the roster row visible as
12
+ * `broken` inside the registry (upstream owns that lifecycle) — the adapter
13
+ * only owns the disposer.
14
+ */
15
+ export function registerPiPreset(ctx) {
16
+ ctx.inject(["agentPresets"], (scoped) => {
17
+ let dispose;
18
+ let settled = false;
19
+ void scoped.agentPresets.register(PI_PRESET).then((unregister) => {
20
+ if (settled) {
21
+ void unregister();
22
+ }
23
+ else {
24
+ dispose = unregister;
25
+ }
26
+ });
27
+ ctx.effect(() => async () => {
28
+ settled = true;
29
+ await dispose?.();
30
+ }, "piAdapter.preset");
31
+ });
32
+ }
@@ -2,6 +2,7 @@ import { randomUUID } from "node:crypto";
2
2
  import { agentEvents } from "@deepseek-ai/dsh-agent";
3
3
  import { Inbox } from "./inbox.js";
4
4
  import { LlmAttemptId, ToolCallId, QUOTA_EXCEEDED_CODE, createAssistantMessage, createSystemMessage, createToolResultMessage, createUserMessage } from "@deepseek-ai/dsh-llm";
5
+ import { withSystemHead } from "../../superd-hub/dist/index.js";
5
6
  import { createScope } from "@deepseek-ai/dsh-scope";
6
7
  import { PI_IDLE_EXIT_MS } from "./knobs.js";
7
8
  import { trace } from "./knobs.js";
@@ -149,8 +150,13 @@ function userMessageText(message) {
149
150
  * drop it.
150
151
  */
151
152
  function isApprovalNarration(message) {
152
- const source = message.source;
153
- return source.kind === "plugin" && source.plugin === "user-approval";
153
+ // 0.1.7: the shared `plugin` source kind is gone (MessageSourceMap is
154
+ // merge-extensible; each producer declares its own kind) — user-approval
155
+ // now carries the dedicated `user-approval` kind.
156
+ // Type-only: loads the `user-approval` MessageSourceMap augmentation
157
+ // (0.1.7: producer-owned source kinds; the shared `plugin` kind is gone).
158
+ // noinspection JSValidateTypes
159
+ return message.source.kind === "user-approval";
154
160
  }
155
161
  /**
156
162
  * Reconstruct a Dash user message from a wire `message_start(role=user)`
@@ -222,7 +228,7 @@ export class PiAgent {
222
228
  this.#loopCtx = loopCtx;
223
229
  this.id = id;
224
230
  this.options = options;
225
- this.session = session;
231
+ this.session = withSystemHead(session, () => createSystemMessage(""));
226
232
  this.#client = client;
227
233
  this.#onIdleExit = onIdleExit;
228
234
  this.#runtimeInfo = runtimeInfo;
@@ -418,20 +424,20 @@ export class PiAgent {
418
424
  if (this.#runtimeInfo === undefined || !this.#turnOpen)
419
425
  return;
420
426
  this.#commitStepStart();
421
- if (this.#step === 0)
427
+ // commitStepStart re-enters #emitSystemMessage (step open → stamp); the
428
+ // outer call must re-check the one-shot flag after the recursion.
429
+ if (this.#systemMessageDone)
422
430
  return;
423
- if (this.session.snapshotEvents().some((event) => event.type === "system/message")) {
424
- this.#systemMessageDone = true;
431
+ if (this.#step === 0)
425
432
  return;
426
- }
427
433
  const text = this.#runtimeInfo.systemPrompt();
428
434
  if (text === undefined || text.trim() === "")
429
435
  return;
430
- this.session.append("system/message", {
431
- turn: this.#dashTurn,
432
- step: this.#step,
433
- message: createSystemMessage(text, "aw.agent-adapter-pi"),
434
- }, { surfaceOp: "append" });
436
+ // v4 protected-head posture: the placeholder head (stamped before the
437
+ // first user message) is REPLACED with the real prompt — an append here
438
+ // would land after user surface nodes and corrupt the log for the 0.1.7
439
+ // reader ("system/message requires a protected first surface head").
440
+ this.session.stampSystemPrompt(this.#dashTurn, this.#step, createSystemMessage(text));
435
441
  this.#systemMessageDone = true;
436
442
  trace(`system/message stamped (${text.length} chars)`);
437
443
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * agent-pi provider — Pi provider plugin for DeepSeek Harness
3
- * (Agent Worlds AW-F, SDK line).
3
+ * (Super D, SDK line).
4
4
  *
5
5
  * Replaces the built-in agent loop with an `AgentFactory` that drives pi
6
6
  * `AgentSession`s in-process (one `PiSessionClient` per session, through the
@@ -28,13 +28,12 @@
28
28
  import { realpathSync, statSync } from "node:fs";
29
29
  import { join } from "node:path";
30
30
  import { Service } from "@deepseek-ai/cordis";
31
- import { emitAgentEvent, installModelSelection } from "@deepseek-ai/dsh-agent";
31
+ import { installModelSelection } from "@deepseek-ai/dsh-agent";
32
32
  import { SessionLogOffset, SessionPreparation, interruptedTurnClosers, } from "@deepseek-ai/dsh-session";
33
33
  import { PiSessionClient } from "./pi-client.js";
34
34
  import { PiAgent } from "./agent.js";
35
35
  import { PiLlmAdapter } from "./adapter.js";
36
- import { SinglePiPresetRoster } from "./agent-preset-pi.js";
37
- import { piAgentPresetProjection } from "./agent-preset-projection.js";
36
+ import { registerPiPreset } from "./agent-preset-pi.js";
38
37
  import { resolvePiStateDir } from "./pi-home.js";
39
38
  import { sessionRecord, upsertSession } from "./session-map.js";
40
39
  import { warmPiCatalog, readPiModelCatalog, piProviderIds, resolvePiSelection, PI_PROVIDER_ID } from "./models.js";
@@ -112,14 +111,12 @@ export class PiProvider extends Service {
112
111
  // nesting it under a child fiber via ctx.plugin hides its @Remote routes
113
112
  // from the gateway and every agentPresets/* call 404s. Register it on
114
113
  // this plugin's own (top-level) fiber instead.
115
- new SinglePiPresetRoster(ctx);
116
- // Drive the `agentPreset` session projection ourselves: the upstream
117
- // registrant lives in the (disabled) dsh-agent-presets package, but the
118
- // Web UI gates the preset chip and header label on
119
- // `projectionValues.agentPreset`.
120
- ctx.inject(["sessionProjections"], (scoped) => {
121
- scoped.sessionProjections.register(piAgentPresetProjection);
122
- });
114
+ // 0.1.7: roster/selection/document RPC + the `agentPreset` session
115
+ // projection all live in the host AgentPresetRegistry (mounted by the
116
+ // dsh-web-app bundle's `agent-preset-registry` row; the adapter patch
117
+ // pins its `default` to the Pi preset). The adapter only registers
118
+ // its one fixed preset into the registry.
119
+ registerPiPreset(ctx);
123
120
  }
124
121
  /**
125
122
  * The factory owns its sessions' route (codex directive parity): a session
@@ -197,7 +194,7 @@ export class PiProvider extends Service {
197
194
  if (typeof resolved === "string" && resolved !== "")
198
195
  return resolved;
199
196
  }
200
- return process.env.DSH_HOME ?? join(process.cwd(), ".tests", "aw");
197
+ return process.env.DSH_HOME ?? join(process.cwd(), ".tests", "superd");
201
198
  }
202
199
  /**
203
200
  * App-wide wiring the adapter owns: register the adapter on a boot
@@ -357,7 +354,7 @@ export class PiProvider extends Service {
357
354
  const loopCtx = this.runtime.ctx;
358
355
  const id = options.resumeSessionId;
359
356
  // Identity ("mapping only") with BLANK-SESSION TOLERANCE (2026-09-18,
360
- // dev-rules §14 i / omp-web doctrine): a session whose pi side never
357
+ // dev-rules §14 i doctrine): a session whose pi side never
361
358
  // materialized (no record, or `sessionFile: null`) resumes AS FRESH —
362
359
  // the lazy shell waits for the first prompt, exactly like create (the
363
360
  // Dash host eagerly resumes on view/model-change, so failing here broke
@@ -547,8 +544,9 @@ async function setupAndPublish(loopCtx, ownerCtx, id, agentOptions, setup, sessi
547
544
  agent.ctx.sessions.announce(session);
548
545
  }
549
546
  detachAgent = loopCtx.agents.enter(agent, parentAgent);
550
- loopCtx.agents.announce(agent);
551
- emitAgentEvent(loopCtx, agent, "agent/session-start", { source });
547
+ // 0.1.6: announce(agent, source) is required, async, and emits agent/created
548
+ // itself — the manual agent/session-start emission is gone upstream.
549
+ await loopCtx.agents.announce(agent, source);
552
550
  let disposed = false;
553
551
  let unfollowOwner;
554
552
  const dispose = async () => {
@@ -16,19 +16,12 @@
16
16
  * pi never reads this tree; it is DSH bookkeeping in the same class as the
17
17
  * DSH session log.
18
18
  */
19
- import { homedir } from "node:os";
20
19
  import { join, resolve } from "node:path";
21
20
  /** Prod homes that must never be resolved into (repo red line). */
22
- const PROD_HOMES = [join(homedir(), ".dsh"), join(homedir(), ".superd")];
23
- export function assertNotProdHome(path, label) {
24
- if (PROD_HOMES.includes(path) || PROD_HOMES.some((p) => path.startsWith(`${p}/`))) {
25
- throw new Error(`pi-home: refusing prod home as ${label}: ${path}`);
26
- }
27
- }
28
21
  /**
29
22
  * Resolve the adapter's DSH-side state dir — `<dshHomePath>/agents/pi`.
30
23
  * Precedence: explicit home (boot-provided `dshHomePath`), then `$DSH_HOME`,
31
- * then the line's historical test-home default. Prod-guarded.
24
+ * then the line's historical test-home default.
32
25
  */
33
26
  export function resolvePiStateDir(home) {
34
27
  if (home !== undefined) {
@@ -37,16 +30,13 @@ export function resolvePiStateDir(home) {
37
30
  // — that tree IS the pi world's root, so the state dir is the home itself
38
31
  // (no second nest). Line/standalone form: nest once under agents/pi.
39
32
  if (resolved.endsWith(join("agents", "pi"))) {
40
- assertNotProdHome(resolved, "pi state dir");
41
33
  return resolved;
42
34
  }
43
35
  const dir = join(resolved, "agents", "pi");
44
- assertNotProdHome(dir, "pi state dir");
45
36
  return dir;
46
37
  }
47
- const fallbackHome = resolve(process.env.DSH_HOME ?? join(process.cwd(), ".tests", "aw"));
38
+ const fallbackHome = resolve(process.env.DSH_HOME ?? join(process.cwd(), ".tests", "superd"));
48
39
  const dir = join(fallbackHome, "agents", "pi");
49
- assertNotProdHome(dir, "pi state dir");
50
40
  return dir;
51
41
  }
52
42
  /** The dsh↔pi session mapping file inside the state dir. */
@@ -1,9 +1,9 @@
1
1
  /**
2
- * aw.agent-adapter-pi — the Pi adapter's WORLD plugin (spec S2):
2
+ * agent-pi — the Pi adapter's WORLD plugin (spec S2):
3
3
  * activation IS roster membership.
4
4
  *
5
- * AW-B URL scheme (DL1–DL5), mirroring `@pgmi-builds/agent-adapter-omp/world`
6
- * and `@pgmi-builds/agent-adapter-codex/world` so the hub sees every foreign
5
+ * AW-B URL scheme (DL1–DL5), mirroring `@pgmi-builds/agent-omp/world`
6
+ * and `@pgmi-builds/agent-codex/world` so the hub sees every foreign
7
7
  * runtime through one shape: the world is spawned as a sibling ROOT context
8
8
  * with NO listener (`worldMountPatches`) and mounts itself under `/pi`.
9
9
  *
@@ -16,12 +16,10 @@
16
16
  import { mkdirSync } from 'node:fs';
17
17
  import { resolveDshHome } from '@deepseek-ai/dsh-home-paths';
18
18
  import { join } from 'node:path';
19
- import { spawnWorld, registerAgent, setReady, registerForeignTarget, registerHostMount, mountWorld, worldMountPatches, provisionWorldProfile, } from '../../agent-hub/dist/index.js';
20
- export const name = 'aw.agent-adapter-pi';
19
+ import { spawnWorld, registerAgent, setReady, registerForeignTarget, registerHostMount, mountWorld, worldMountPatches, provisionWorldProfile, resolveInstallAnchor, } from '../../superd-hub/dist/index.js';
20
+ export const name = 'agent-pi';
21
21
  /** Runtime key — also the mount label. */
22
22
  const KEY = 'pi';
23
- const ANCHOR = process.env.SUPERD_DSH_ANCHOR
24
- ?? '/home/u1/.local/lib/node_modules/@deepseek-ai/dsh/package.json';
25
23
  export function apply(ctx) {
26
24
  registerAgent({ key: KEY, label: 'Pi', ready: false });
27
25
  // Harness resolver (env → ~/.dsh): a consumer install has no DSH_HOME and
@@ -35,12 +33,10 @@ export function apply(ctx) {
35
33
  const worldHome = join(root, 'agents', KEY);
36
34
  mkdirSync(join(worldHome, 'profiles'), { recursive: true });
37
35
  // Publish story: a foreign install has no line bootstrap, so the nested
38
- // profile + @pgmi-builds links are provisioned HERE (idempotent; dev lines
39
- // keep parity — smoke.mjs wrote the same layout, and AW_BARE_BASE still
40
- // overrides the resolved base).
41
- const bareBase = provisionWorldProfile({
36
+ // profile + @pgmi-builds links are provisioned HERE (idempotent).
37
+ provisionWorldProfile({
42
38
  key: KEY,
43
- adapterPkg: '@pgmi-builds/agent-adapter-pi',
39
+ adapterPkg: '@pgmi-builds/agent-pi',
44
40
  worldHome,
45
41
  });
46
42
  const world = (async () => {
@@ -60,16 +56,15 @@ export function apply(ctx) {
60
56
  authorize: (req, res) => connection.authorizeIndex(req, res),
61
57
  });
62
58
  const ctxW = await spawnWorld({
63
- appName: `aw-${KEY}`,
59
+ appName: `superd-${KEY}`,
64
60
  profileName: 'web',
65
- installAnchor: ANCHOR,
61
+ installAnchor: resolveInstallAnchor(ctx), // lazy: never at module scope — import must stay side-effect-free
66
62
  home: worldHome,
67
63
  dataHome: worldHome,
68
- // Adapter-local bundle names resolve from the profile's own
69
- // node_modules (heal owns @deepseek-ai there; @pgmi-builds links are
70
- // provisioned by provisionWorldProfile above, or by the line bootstrap
71
- // when the adapter package was not resolvable — env wins over both).
72
- bareModuleBaseUrl: process.env.AW_BARE_BASE ?? bareBase ?? undefined,
64
+ // The host's live table carries this world: spawnWorld republishes a
65
+ // widened successor before boot imports anything (spec §2.1), and
66
+ // @pgmi-builds rows resolve from the profile-local links written above.
67
+ host: ctx,
73
68
  extraPatches: worldMountPatches(KEY),
74
69
  });
75
70
  const gateway = ctxW.get('typertGateway');
@@ -85,7 +80,7 @@ export function apply(ctx) {
85
80
  ctx.effect?.(() => () => {
86
81
  mounted.dispose();
87
82
  dropHostMount();
88
- }, `aw.agent-adapter-${KEY}: mount`);
83
+ }, `agent-${KEY}: mount`);
89
84
  return ctxW;
90
85
  })().catch((cause) => {
91
86
  // A failed world degrades to a not-ready roster row; a rejected provided
@@ -93,5 +88,5 @@ export function apply(ctx) {
93
88
  console.error(`[super-dsh] ${KEY} world failed:`, cause);
94
89
  return null;
95
90
  });
96
- ctx.provide(`aw.world.${KEY}`, world);
91
+ ctx.provide(`superd.world.${KEY}`, world);
97
92
  }
@@ -1,7 +1,7 @@
1
1
  {
2
- "name": "@pgmi-builds/agent-adapter-pi",
2
+ "name": "@pgmi-builds/agent-pi",
3
3
  "version": "0.1.0",
4
- "description": "Pi provider for DeepSeek Harness (dsh) — an AgentFactory that embeds the pi coding agent in-process via the @earendil-works/pi-coding-agent SDK and bridges pi's session surface into Dash Agent/Session contracts (Agent Worlds AW-F). pi keeps its native data home ~/.pi (2026-09-17 ruling).",
4
+ "description": "Pi provider for DeepSeek Harness (dsh) — an AgentFactory that embeds the pi coding agent in-process via the @earendil-works/pi-coding-agent SDK and bridges pi's session surface into Dash Agent/Session contracts . pi keeps its native data home ~/.pi (2026-09-17 ruling).",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": "./dist/index.js",
@@ -23,18 +23,18 @@
23
23
  },
24
24
  "dependencies": {
25
25
  "@earendil-works/pi-coding-agent": "0.84.2",
26
- "@pgmi-builds/agent-hub": "file:../agent-hub",
27
- "zod": "3.25.76"
26
+ "zod": "4.4.3"
28
27
  },
29
28
  "peerDependencies": {
30
29
  "@deepseek-ai/cordis": "^4.0.1",
31
- "@deepseek-ai/dsh-agent": "0.1.5-rc.2",
32
- "@deepseek-ai/dsh-agent-presets": "0.1.5-rc.2",
33
- "@deepseek-ai/dsh-llm": "0.1.5-rc.2",
34
- "@deepseek-ai/dsh-scope": "0.1.5-rc.2",
35
- "@deepseek-ai/dsh-session": "0.1.5-rc.2",
36
- "@deepseek-ai/dsh-session-persistence": "0.1.5-rc.2",
37
- "@deepseek-ai/dsh-typert-protocol": "0.1.5-rc.2"
30
+ "@deepseek-ai/dsh-agent": ">=0.1.5-0 <0.3.0-0",
31
+ "@deepseek-ai/dsh-agent-presets": ">=0.1.5-0 <0.3.0-0",
32
+ "@deepseek-ai/dsh-llm": ">=0.1.5-0 <0.3.0-0",
33
+ "@deepseek-ai/dsh-scope": ">=0.1.5-0 <0.3.0-0",
34
+ "@deepseek-ai/dsh-session": ">=0.1.5-0 <0.3.0-0",
35
+ "@deepseek-ai/dsh-session-persistence": ">=0.1.5-0 <0.3.0-0",
36
+ "@deepseek-ai/dsh-typert-protocol": ">=0.1.5-0 <0.3.0-0",
37
+ "@pgmi-builds/superd-hub": "*"
38
38
  },
39
39
  "peerDependenciesMeta": {
40
40
  "@deepseek-ai/cordis": {
@@ -60,6 +60,9 @@
60
60
  },
61
61
  "@deepseek-ai/dsh-typert-protocol": {
62
62
  "optional": true
63
+ },
64
+ "@pgmi-builds/superd-hub": {
65
+ "optional": true
63
66
  }
64
67
  },
65
68
  "devDependencies": {
package/cordis.patch.yml CHANGED
@@ -1,40 +1,50 @@
1
- # super-dsh — the Agent Worlds composite bundle (one `dsh plugin add` face).
1
+ # super-dsh — the Super D composite bundle (one `dsh plugin add` face).
2
2
  #
3
3
  # better-dsh shape: ONE package, components are this package's own subpath
4
4
  # exports, so every row below is individually toggleable on the plugin page
5
5
  # (cordis hmr; docs/06 §二.5 — insert rows = the "Components" lines).
6
6
  #
7
- # - super-dsh/hub the hub: selector + roster + per-world mount
8
- # carrier + V5 gateway delegation (wraps the live
9
- # typertGateway; upstream dispatch untouched)
10
- # - super-dsh/world/<label> one world plugin per adapter (activation IS
7
+ # - super-dsh/hub the hub host library (selector + roster +
8
+ # per-world mount carrier + V5 gateway
9
+ # delegation) — ships for the adapters' relative
10
+ # imports (world spawn/mount/carrier/web-trust);
11
+ # the ctx0 control-plane row and ui client half
12
+ # were stripped in 0.1.4 (archival final state
13
+ # of the multi-webui path)
14
+ # - super-dsh/agents/<label> one world plugin per adapter (activation IS
11
15
  # roster membership, S2) — each spawns its own
12
16
  # zero-port sibling root, mounted under /<label>
13
17
  # - super-dsh/join the generic hub joiner for the standalone
14
18
  # claude adapter (R2)
19
+ # - super-dsh/web-trust the page-trust component (ported from
20
+ # better-dsh web-trust, authorities leg): the
21
+ # browser-side twin of the server trustedHosts
22
+ # fence — declares trusted page authorities so
23
+ # the Web UI treats a non-loopback page (Caddy
24
+ # domain / LAN IP) as loopback-equivalent.
25
+ # On/off: row `disabled: true`, or config
26
+ # `trustedPageAuthorities: []` (inert). Default
27
+ # derives from the trusted-hosts env.
15
28
  #
16
29
  # Profile-layer values (webserver port/host, settings path) stay in the USER's
17
30
  # profile patch layer, never here.
18
31
  - insert:
19
- # BARE package row: subpath rows (…/world/omp) are permanently not client
20
- # rows in client-modules' scan (exactPackageSpecifier), so THIS row is
21
- # what registers the package's client half — the sidebar selector.
22
- - id: agent-hub
23
- name: 'super-dsh'
24
- - id: aw-agent-adapter-omp
25
- name: 'super-dsh/world/omp'
26
- - id: aw-agent-adapter-codex
27
- name: 'super-dsh/world/codex'
28
- - id: aw-agent-adapter-pi
29
- name: 'super-dsh/world/pi'
30
- - id: aw-agent-adapter-hermes
31
- name: 'super-dsh/world/hermes'
32
- - id: aw-agent-adapter-agy
33
- name: 'super-dsh/world/agy'
32
+ - id: superd-web-trust
33
+ name: 'super-dsh/web-trust'
34
+ - id: agent-omp
35
+ name: 'super-dsh/agents/omp'
36
+ - id: agent-codex
37
+ name: 'super-dsh/agents/codex'
38
+ - id: agent-pi
39
+ name: 'super-dsh/agents/pi'
40
+ - id: agent-hermes
41
+ name: 'super-dsh/agents/hermes'
42
+ - id: agent-agy
43
+ name: 'super-dsh/agents/agy'
34
44
  # R2 (2026-09-16): the claude adapter ships STANDALONE only — its /world
35
45
  # entry is inert. The HUB side joins it: one generic joiner row with the
36
46
  # key; spawn/roster/mount wiring lives in super-dsh/join.
37
- - id: aw-world-join-claude
47
+ - id: superd-join-claude
38
48
  name: 'super-dsh/join'
39
49
  config:
40
50
  key: claude