shennian 0.4.10 → 0.4.13

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 (125) hide show
  1. package/dist/publish-build-manifest.json +185 -55
  2. package/dist/src/agents/acp/adapter.d.ts +78 -0
  3. package/dist/src/agents/acp/adapter.js +3 -0
  4. package/dist/src/agents/acp/auth-state.d.ts +3 -0
  5. package/dist/src/agents/acp/auth-state.js +1 -0
  6. package/dist/src/agents/acp/auth.d.ts +7 -0
  7. package/dist/src/agents/acp/auth.js +1 -0
  8. package/dist/src/agents/acp/capability-cache.d.ts +14 -0
  9. package/dist/src/agents/acp/capability-cache.js +2 -0
  10. package/dist/src/agents/acp/catalog.d.ts +11 -0
  11. package/dist/src/agents/acp/catalog.js +2 -0
  12. package/dist/src/agents/acp/client-services.d.ts +32 -0
  13. package/dist/src/agents/acp/client-services.js +3 -0
  14. package/dist/src/agents/acp/discovery.d.ts +9 -0
  15. package/dist/src/agents/acp/discovery.js +1 -0
  16. package/dist/src/agents/acp/events.d.ts +4 -0
  17. package/dist/src/agents/acp/events.js +3 -0
  18. package/dist/src/agents/acp/manifests.d.ts +63 -0
  19. package/dist/src/agents/acp/manifests.js +2 -0
  20. package/dist/src/agents/acp/metrics.d.ts +24 -0
  21. package/dist/src/agents/acp/metrics.js +1 -0
  22. package/dist/src/agents/acp/package-commands.d.ts +4 -0
  23. package/dist/src/agents/acp/package-commands.js +1 -0
  24. package/dist/src/agents/acp/process-client.d.ts +39 -0
  25. package/dist/src/agents/acp/process-client.js +1 -0
  26. package/dist/src/agents/acp/process-tree.d.ts +2 -0
  27. package/dist/src/agents/acp/process-tree.js +1 -0
  28. package/dist/src/agents/acp/types.d.ts +31 -0
  29. package/dist/src/agents/acp/types.js +1 -0
  30. package/dist/src/agents/acp/watcher.d.ts +22 -0
  31. package/dist/src/agents/acp/watcher.js +1 -0
  32. package/dist/src/agents/adapter.d.ts +96 -2
  33. package/dist/src/agents/adapter.js +1 -1
  34. package/dist/src/agents/claude.d.ts +14 -0
  35. package/dist/src/agents/claude.js +5 -5
  36. package/dist/src/agents/codex.d.ts +6 -0
  37. package/dist/src/agents/codex.js +1 -1
  38. package/dist/src/agents/command-spec.d.ts +5 -0
  39. package/dist/src/agents/command-spec.js +3 -3
  40. package/dist/src/agents/cursor.d.ts +6 -0
  41. package/dist/src/agents/cursor.js +1 -1
  42. package/dist/src/agents/custom-recovery-conformance.d.ts +2 -0
  43. package/dist/src/agents/custom-recovery-conformance.js +2 -0
  44. package/dist/src/agents/custom.d.ts +9 -0
  45. package/dist/src/agents/custom.js +4 -4
  46. package/dist/src/agents/detect.d.ts +11 -2
  47. package/dist/src/agents/detect.js +1 -1
  48. package/dist/src/agents/gemini.d.ts +6 -0
  49. package/dist/src/agents/gemini.js +1 -1
  50. package/dist/src/agents/manager.d.ts +2 -0
  51. package/dist/src/agents/manager.js +5 -5
  52. package/dist/src/agents/model-registry/service.js +1 -1
  53. package/dist/src/agents/opencode.d.ts +6 -0
  54. package/dist/src/agents/opencode.js +1 -1
  55. package/dist/src/agents/pi-coding-agent.d.ts +6 -0
  56. package/dist/src/agents/pi-coding-agent.js +4 -4
  57. package/dist/src/agents/workbuddy.d.ts +6 -0
  58. package/dist/src/agents/workbuddy.js +2 -2
  59. package/dist/src/commands/agent.d.ts +2 -0
  60. package/dist/src/commands/agent.js +2 -0
  61. package/dist/src/commands/daemon.d.ts +6 -2
  62. package/dist/src/commands/daemon.js +19 -23
  63. package/dist/src/commands/pair.js +10 -10
  64. package/dist/src/commands/upgrade.d.ts +7 -1
  65. package/dist/src/commands/upgrade.js +1 -1
  66. package/dist/src/config/index.d.ts +1 -1
  67. package/dist/src/config/index.js +2 -2
  68. package/dist/src/daemon-ipc/control.d.ts +16 -0
  69. package/dist/src/daemon-ipc/control.js +1 -0
  70. package/dist/src/index.js +3 -3
  71. package/dist/src/log-reporter.d.ts +23 -0
  72. package/dist/src/log-reporter.js +1 -1
  73. package/dist/src/relay/client.d.ts +1 -0
  74. package/dist/src/relay/client.js +1 -1
  75. package/dist/src/room/activation-service.d.ts +2 -0
  76. package/dist/src/room/activation-service.js +5 -5
  77. package/dist/src/session/handlers/agents.d.ts +1 -0
  78. package/dist/src/session/handlers/agents.js +1 -1
  79. package/dist/src/session/handlers/chat.d.ts +3 -0
  80. package/dist/src/session/handlers/chat.js +2 -2
  81. package/dist/src/session/manager.d.ts +23 -2
  82. package/dist/src/session/manager.js +3 -1
  83. package/dist/src/session/queue.d.ts +7 -1
  84. package/dist/src/session/queue.js +8 -8
  85. package/dist/src/session/run-recovery/barrier.d.ts +12 -0
  86. package/dist/src/session/run-recovery/barrier.js +1 -0
  87. package/dist/src/session/run-recovery/coordinator.d.ts +32 -0
  88. package/dist/src/session/run-recovery/coordinator.js +1 -0
  89. package/dist/src/session/run-recovery/journal.d.ts +30 -0
  90. package/dist/src/session/run-recovery/journal.js +2 -0
  91. package/dist/src/session/run-recovery/schema.d.ts +43 -0
  92. package/dist/src/session/run-recovery/schema.js +1 -0
  93. package/dist/src/session/types.d.ts +10 -0
  94. package/dist/src/upgrade/engine.d.ts +6 -5
  95. package/dist/src/upgrade/engine.js +2 -2
  96. package/dist/src/upgrade/scheduler.d.ts +14 -0
  97. package/dist/src/upgrade/scheduler.js +1 -1
  98. package/dist/src/upgrade/updater-bootstrap.d.ts +12 -0
  99. package/dist/src/upgrade/updater-bootstrap.js +2 -0
  100. package/dist/src/upgrade/updater-launcher.d.ts +28 -0
  101. package/dist/src/upgrade/updater-launcher.js +3 -0
  102. package/dist/src/upgrade/updater-protocol.d.ts +37 -0
  103. package/dist/src/upgrade/updater-protocol.js +1 -0
  104. package/dist/src/upgrade/updater-worker.d.ts +11 -0
  105. package/dist/src/upgrade/updater-worker.js +2 -0
  106. package/node_modules/@shennian/wire/dist/events.d.ts +31 -0
  107. package/node_modules/@shennian/wire/dist/index.d.ts +1 -0
  108. package/node_modules/@shennian/wire/dist/index.js +1 -0
  109. package/node_modules/@shennian/wire/dist/machine.d.ts +49 -1
  110. package/node_modules/@shennian/wire/dist/message-payload.d.ts +1 -0
  111. package/node_modules/@shennian/wire/dist/message-payload.js +4 -1
  112. package/node_modules/@shennian/wire/dist/methods.d.ts +1 -1
  113. package/node_modules/@shennian/wire/dist/relay-connectivity.d.ts +30 -0
  114. package/node_modules/@shennian/wire/dist/relay-connectivity.js +29 -0
  115. package/node_modules/@shennian/wire/dist/session-sync.d.ts +2 -2
  116. package/node_modules/@shennian/wire/dist/session-sync.js +2 -0
  117. package/node_modules/@shennian/wire/dist/session.d.ts +86 -1
  118. package/node_modules/@shennian/wire/dist/session.js +5 -1
  119. package/package.json +5 -3
  120. package/dist/native/macos-background-client/Shennian.app/Contents/CodeResources +0 -0
  121. package/dist/native/macos-background-client/Shennian.app/Contents/Info.plist +0 -17
  122. package/dist/native/macos-background-client/Shennian.app/Contents/MacOS/ShennianClientLauncher +0 -0
  123. package/dist/native/macos-background-client/Shennian.app/Contents/Resources/en.lproj/InfoPlist.strings +0 -2
  124. package/dist/native/macos-background-client/Shennian.app/Contents/Resources/zh-Hans.lproj/InfoPlist.strings +0 -2
  125. package/dist/native/macos-background-client/Shennian.app/Contents/_CodeSignature/CodeResources +0 -153
@@ -28,6 +28,7 @@ export type ApprovalPendingPayload = {
28
28
  content: string;
29
29
  source?: string;
30
30
  actionHint?: string;
31
+ permission?: import('./events.ts').AcpPermissionPrompt;
31
32
  };
32
33
  export type ChannelDeliveryStatusPayload = {
33
34
  v: 1;
@@ -180,7 +180,10 @@ export function buildApprovalPendingPayload(input) {
180
180
  title: input?.title?.trim() || '需要用户确认',
181
181
  content: input?.content?.trim() || 'Codex 正在等待用户确认后继续。',
182
182
  source: input?.source?.trim() || 'codex',
183
- actionHint: input?.actionHint?.trim() || '当前神念暂不支持远程确认,请回到运行 Codex 的电脑/终端完成确认。',
183
+ actionHint: input?.permission
184
+ ? input?.actionHint?.trim()
185
+ : input?.actionHint?.trim() || '当前神念暂不支持远程确认,请回到运行 Codex 的电脑/终端完成确认。',
186
+ ...(input?.permission ? { permission: input.permission } : {}),
184
187
  });
185
188
  }
186
189
  export function isSystemEnvironmentContextPayload(payload) {
@@ -1 +1 @@
1
- export type ReqMethod = 'chat.send' | 'chat.enqueue' | 'chat.queue.get' | 'chat.queue.edit' | 'chat.queue.delete' | 'chat.abort' | 'session.resume' | 'session.history' | 'session.history.open' | 'session.history.sync' | 'session.history.page' | 'session.history.close' | 'session.body.replica.subscribe' | 'session.body.replica.unsubscribe' | 'session.index.update' | 'session.deletions.sync' | 'session.deletions.ack' | 'session.message.status' | 'voice.session.body.window' | 'session.refresh' | 'session.tool.detail' | 'session.title.set' | 'session.title.generate' | 'fs.ls' | 'fs.read' | 'fs.write' | 'fs.export.markdown-pdf' | 'fs.export.markdown-pdf.setup' | 'fs.archive.zip' | 'fs.transfer.start' | 'fs.transfer.chunk' | 'fs.transfer.finish' | 'fs.transfer.abort' | 'fs.rename' | 'skill.list' | 'skill.install' | 'skill.doctor' | 'skill.setup' | 'skill.use' | 'region.probe' | 'region.switch' | 'upgrade.start' | 'upgrade.status' | 'upgrade.set-policy' | 'machine.remote-access.pause' | 'agents.refresh' | 'models.refresh' | 'agent.config.get' | 'agent.config.upsert' | 'agent.config.clear' | 'agent.config.test' | 'agent.workspace.validate' | 'agent.capabilities.list' | 'manager.channel.get' | 'manager.channel.upsert' | 'session.wechat-rpa.channel.get' | 'session.wechat-rpa.channel.upsert' | 'session.wechat-rpa.channel.sync' | 'session.wechat-rpa.outbound.cancel' | 'manager.wechat-rpa.channel.get' | 'manager.wechat-rpa.channel.upsert' | 'manager.wechat-rpa.channel.sync' | 'manager.wechat-rpa.outbound.cancel' | 'wechat-rpa.helper.runtime' | 'wecom.send' | 'external.send' | 'room.sync' | 'room.send' | 'room.bind' | 'room.agent.bind-managed' | 'room.agent.restart-managed' | 'room.unbind';
1
+ export type ReqMethod = 'chat.send' | 'chat.enqueue' | 'chat.queue.get' | 'chat.queue.edit' | 'chat.queue.delete' | 'chat.abort' | 'session.resume' | 'session.history' | 'session.history.open' | 'session.history.sync' | 'session.history.page' | 'session.history.close' | 'session.body.replica.subscribe' | 'session.body.replica.unsubscribe' | 'session.index.update' | 'session.deletions.sync' | 'session.deletions.ack' | 'session.message.status' | 'voice.session.body.window' | 'session.refresh' | 'session.tool.detail' | 'session.title.set' | 'session.title.generate' | 'fs.ls' | 'fs.read' | 'fs.write' | 'fs.export.markdown-pdf' | 'fs.export.markdown-pdf.setup' | 'fs.archive.zip' | 'fs.transfer.start' | 'fs.transfer.chunk' | 'fs.transfer.finish' | 'fs.transfer.abort' | 'fs.rename' | 'skill.list' | 'skill.install' | 'skill.doctor' | 'skill.setup' | 'skill.use' | 'region.probe' | 'region.switch' | 'upgrade.start' | 'upgrade.status' | 'upgrade.set-policy' | 'machine.remote-access.pause' | 'agents.refresh' | 'models.refresh' | 'agent.config.get' | 'agent.config.upsert' | 'agent.config.clear' | 'agent.config.test' | 'agent.workspace.validate' | 'agent.capabilities.list' | 'agent.permission.respond' | 'agent.auth.start' | 'agent.auth.logout' | 'agent.session-options.get' | 'agent.external-sessions.list' | 'agent.external-sessions.import' | 'agent.external-sessions.close' | 'agent.external-sessions.delete' | 'manager.channel.get' | 'manager.channel.upsert' | 'session.wechat-rpa.channel.get' | 'session.wechat-rpa.channel.upsert' | 'session.wechat-rpa.channel.sync' | 'session.wechat-rpa.outbound.cancel' | 'manager.wechat-rpa.channel.get' | 'manager.wechat-rpa.channel.upsert' | 'manager.wechat-rpa.channel.sync' | 'manager.wechat-rpa.outbound.cancel' | 'wechat-rpa.helper.runtime' | 'wecom.send' | 'external.send' | 'room.sync' | 'room.send' | 'room.bind' | 'room.agent.bind-managed' | 'room.agent.restart-managed' | 'room.unbind';
@@ -0,0 +1,30 @@
1
+ export type RelayConnectivityPhase = 'connecting' | 'connected' | 'recovering' | 'blocked' | 'offline';
2
+ export type RelayConnectivityReason = 'initial_connect' | 'network_offline' | 'transient_transport' | 'server_unavailable' | 'auth_required' | 'version_unsupported' | 'permission_revoked' | 'plan_required' | 'machine_unavailable' | 'unknown';
3
+ export type RelayConnectivitySnapshot = {
4
+ phase: RelayConnectivityPhase;
5
+ reason: RelayConnectivityReason;
6
+ closeCode: number | null;
7
+ closeReason: string | null;
8
+ retryable: boolean;
9
+ retryAttempt: number;
10
+ nextRetryAt: number | null;
11
+ disconnectedAt: number | null;
12
+ lastConnectedAt: number | null;
13
+ connectionId: string | null;
14
+ };
15
+ export type RelayConnectivityEventName = 'relay_connect_started' | 'relay_connected' | 'relay_disconnected' | 'relay_retry_scheduled' | 'relay_watchdog_rebuild' | 'relay_manual_retry' | 'relay_recovery_succeeded' | 'relay_recovery_failed';
16
+ export type RelayConnectivityEvent = {
17
+ name: RelayConnectivityEventName;
18
+ snapshot: RelayConnectivitySnapshot;
19
+ at: number;
20
+ durationMs?: number;
21
+ };
22
+ export type RelayCloseClassification = {
23
+ reason: RelayConnectivityReason;
24
+ retryable: boolean;
25
+ };
26
+ /**
27
+ * The server owns close-code meaning. Keeping this map in Wire prevents App,
28
+ * Shared and Server from drifting into different user-facing explanations.
29
+ */
30
+ export declare function classifyRelayClose(code: number, closeReason?: string): RelayCloseClassification;
@@ -0,0 +1,29 @@
1
+ // @arch docs/features/app-relay-reconnect-and-connectivity-feedback-todo.md#五、目标连接模型
2
+ // @test packages/shared/src/__tests__/relay.test.ts
3
+ /**
4
+ * The server owns close-code meaning. Keeping this map in Wire prevents App,
5
+ * Shared and Server from drifting into different user-facing explanations.
6
+ */
7
+ export function classifyRelayClose(code, closeReason = '') {
8
+ if (code === 4001 || code === 4009)
9
+ return { reason: 'auth_required', retryable: false };
10
+ if (code === 4003 || code === 4403 || code === 4411) {
11
+ return { reason: 'permission_revoked', retryable: false };
12
+ }
13
+ if (code === 4402)
14
+ return { reason: 'plan_required', retryable: false };
15
+ if (code === 4406)
16
+ return { reason: 'version_unsupported', retryable: false };
17
+ if (code === 4004)
18
+ return { reason: 'machine_unavailable', retryable: true };
19
+ if (code === 4008 || code === 1012 || code === 1013) {
20
+ return { reason: 'server_unavailable', retryable: true };
21
+ }
22
+ if (code === 0 || code === 1006 || code === 1011) {
23
+ return { reason: 'transient_transport', retryable: true };
24
+ }
25
+ if (/upgrade|required|protocol|epoch|capabilit/i.test(closeReason)) {
26
+ return { reason: 'version_unsupported', retryable: false };
27
+ }
28
+ return { reason: 'unknown', retryable: true };
29
+ }
@@ -21,8 +21,8 @@ export declare const SESSION_SYNC_REQUIRED_CAPABILITIES: readonly ["session_inde
21
21
  * epoch-wide minimum gate. This lets the App roll out background replication
22
22
  * while old daemons keep serving the compatible visible-session snapshot path.
23
23
  */
24
- export declare const SESSION_SYNC_ADDITIVE_CAPABILITIES: readonly ["session_body_replica_v1", "session_body_replica_stream_v1"];
25
- export declare const SESSION_SYNC_ADVERTISED_CAPABILITIES: readonly ["session_index_v1", "session_body_revision_v1", "session_history_subscription_v1", "local_canonical_v1", "session_title_authority_v1", "session_title_seed_v1", "session_tool_detail_v1", "voice_session_body_relay_v1", "native_source_tombstone_v1", "session_durable_send_v1", "daemon_installation_identity_v1", "session_user_boundary_v1", "session_terminal_outbox_v1", "session_list_preview_v1", "session_attention_v1", "session_data_epoch_v2", "session_structured_rejection_v2", "machine_personal_authority_v2", "session_body_replica_v1", "session_body_replica_stream_v1"];
24
+ export declare const SESSION_SYNC_ADDITIVE_CAPABILITIES: readonly ["session_body_replica_v1", "session_body_replica_stream_v1", "active_run_recovery_v1", "external_updater_v1"];
25
+ export declare const SESSION_SYNC_ADVERTISED_CAPABILITIES: readonly ["session_index_v1", "session_body_revision_v1", "session_history_subscription_v1", "local_canonical_v1", "session_title_authority_v1", "session_title_seed_v1", "session_tool_detail_v1", "voice_session_body_relay_v1", "native_source_tombstone_v1", "session_durable_send_v1", "daemon_installation_identity_v1", "session_user_boundary_v1", "session_terminal_outbox_v1", "session_list_preview_v1", "session_attention_v1", "session_data_epoch_v2", "session_structured_rejection_v2", "machine_personal_authority_v2", "session_body_replica_v1", "session_body_replica_stream_v1", "active_run_recovery_v1", "external_updater_v1"];
26
26
  export declare const SESSION_SYNC_EVENT_NAMES: readonly ["session.index.updated", "session.body.delta", "session.body.replica.delta", "session.body.replica.error"];
27
27
  export declare const SESSION_HISTORY_LIMITS: {
28
28
  readonly defaultSnapshotMessages: 100;
@@ -38,6 +38,8 @@ export const SESSION_SYNC_REQUIRED_CAPABILITIES = [
38
38
  export const SESSION_SYNC_ADDITIVE_CAPABILITIES = [
39
39
  'session_body_replica_v1',
40
40
  'session_body_replica_stream_v1',
41
+ 'active_run_recovery_v1',
42
+ 'external_updater_v1',
41
43
  ];
42
44
  export const SESSION_SYNC_ADVERTISED_CAPABILITIES = [
43
45
  ...SESSION_SYNC_REQUIRED_CAPABILITIES,
@@ -2,7 +2,9 @@ import type { NativeSessionSourceMode } from './native-session.js';
2
2
  import type { PersonalAttachmentReference, PersonalSyncIdentity, SessionBodyStorageMode, SessionTitleSource } from './session-sync.js';
3
3
  export type BuiltinAgentType = 'claude' | 'codex' | 'workbuddy' | 'gemini' | 'cursor' | 'openclaw' | 'opencode' | 'pi' | 'pi-coding-agent' | 'manager';
4
4
  export type CustomAgentType = `custom:${string}`;
5
- export type AgentType = BuiltinAgentType | CustomAgentType;
5
+ /** Stable Agent Client Protocol integrations discovered on the target machine. */
6
+ export type AcpAgentType = `acp:${string}`;
7
+ export type AgentType = BuiltinAgentType | CustomAgentType | AcpAgentType;
6
8
  /** The external Codex owner stopped its last turn, so its native queue is paused. */
7
9
  export declare const CODEX_DESKTOP_SEND_UNAVAILABLE = "codex_desktop_send_unavailable";
8
10
  export declare const DISABLED_BUILTIN_AGENT_TYPES: readonly ["gemini", "openclaw"];
@@ -21,6 +23,15 @@ export type ModelInfo = {
21
23
  defaultReasoningEffort?: string;
22
24
  additionalSpeedTiers?: string[];
23
25
  };
26
+ /** Runtime options returned by an active ACP session; absent before session/new or load. */
27
+ export type AcpSessionOptions = {
28
+ models: ModelInfo[];
29
+ modes: Array<{
30
+ id: string;
31
+ name: string;
32
+ description?: string;
33
+ }>;
34
+ };
24
35
  export type AgentConfigStatus = 'missing' | 'detected' | 'managed' | 'error';
25
36
  export type AgentConfigSummary = {
26
37
  /** Configuration state on the target machine; secrets are never included. */
@@ -45,9 +56,79 @@ export type AgentRuntimeSummary = {
45
56
  /** Shennian never upgrades third-party Agents automatically. */
46
57
  upgradeAction?: 'manual';
47
58
  };
59
+ export type AgentIntegration = 'deep' | 'acp';
60
+ export type AgentAuthState = 'ready' | 'required' | 'unknown' | 'error';
61
+ export type AcpCapabilitySummary = {
62
+ protocolVersion: 1;
63
+ listSessions: boolean;
64
+ loadSession: boolean;
65
+ resumeSession: boolean;
66
+ closeSession: boolean;
67
+ deleteSession: boolean;
68
+ terminal: boolean;
69
+ fileRead: boolean;
70
+ fileWrite: boolean;
71
+ permission: boolean;
72
+ modelConfig: boolean;
73
+ };
74
+ export type AcpAuthMethodSummary = {
75
+ id: string;
76
+ name: string;
77
+ type: 'agent' | 'terminal';
78
+ };
79
+ export type AgentDisplayMetadata = {
80
+ name: string;
81
+ abbreviation?: string;
82
+ version?: string;
83
+ };
84
+ export type AcpCatalogPlatform = 'darwin-aarch64' | 'darwin-x86_64' | 'linux-aarch64' | 'linux-x86_64' | 'windows-aarch64' | 'windows-x86_64';
85
+ export type AcpCatalogCandidate = {
86
+ id: string;
87
+ name: string;
88
+ version: string;
89
+ commands: string[];
90
+ args: string[];
91
+ /** Package hints are inspected locally only; the daemon never installs them. */
92
+ npmPackage?: string;
93
+ uvPackage?: string;
94
+ website?: string;
95
+ duplicateOf?: BuiltinAgentType;
96
+ };
97
+ export type AcpCatalogSnapshot = {
98
+ revision: string;
99
+ digest: string;
100
+ fetchedAt: string;
101
+ sourceVersion: string;
102
+ platform: AcpCatalogPlatform;
103
+ candidates: AcpCatalogCandidate[];
104
+ };
105
+ export type AcpExternalSessionInfo = {
106
+ agentSessionId: string;
107
+ cwd: string;
108
+ title?: string;
109
+ updatedAt?: string;
110
+ };
111
+ /** Complete scope for an external ACP session; vendor ids are never global. */
112
+ export type AcpExternalSessionIdentity = {
113
+ machineId: string;
114
+ agentType: AcpAgentType;
115
+ agentSessionId: string;
116
+ };
48
117
  export type AgentInfo = {
49
118
  type: AgentType;
50
119
  models: ModelInfo[];
120
+ /** User-facing grouping. Omitted by older daemons and interpreted as deep. */
121
+ integration?: AgentIntegration;
122
+ /** Non-secret metadata used for dynamic ACP display fallbacks. */
123
+ display?: AgentDisplayMetadata;
124
+ /** Stable ACP v1 capabilities negotiated with the installed local Agent. */
125
+ acpCapabilities?: AcpCapabilitySummary;
126
+ /** Non-secret authentication choices advertised during ACP initialize. */
127
+ acpAuthMethods?: AcpAuthMethodSummary[];
128
+ /** Conservative auth projection; authMethods alone never imply required. */
129
+ authState?: AgentAuthState;
130
+ /** Registry snapshot used to discover the Agent, when applicable. */
131
+ catalogRevision?: string;
51
132
  /** True when this provider can back a stable Shennian Agent and managed Room session. */
52
133
  supportsManagedAgent?: boolean;
53
134
  /** True when Manager mode can create this provider as a worker. */
@@ -82,6 +163,8 @@ export type SessionUserState = {
82
163
  lastReadAttentionCount?: number;
83
164
  lastReadAttentionId?: string | null;
84
165
  manualUnread?: boolean;
166
+ /** Local desired read watermark has not yet been acknowledged by Server. */
167
+ readSyncPending?: boolean;
85
168
  updatedAt: string;
86
169
  };
87
170
  /** Exact lightweight index state the user actually saw before marking a Session read. */
@@ -300,6 +383,8 @@ export type ChatQueueSnapshot = PersonalSyncIdentity & {
300
383
  export type ChatEnqueueParams = ChatSendParams & {
301
384
  queueMessageId?: string;
302
385
  origin?: 'app' | 'external';
386
+ /** Relay-attested. Clients must not set this field directly. */
387
+ managedAgentDirect?: true;
303
388
  };
304
389
  export type ChatQueueGetParams = PersonalSyncIdentity & {
305
390
  sessionId: string;
@@ -1,3 +1,5 @@
1
+ // @arch docs/features/app-relay-reconnect-and-connectivity-feedback-todo.md#p4已读水位恢复
2
+ // @test packages/shared/src/__tests__/sync-engine.test.ts
1
3
  /** The external Codex owner stopped its last turn, so its native queue is paused. */
2
4
  export const CODEX_DESKTOP_SEND_UNAVAILABLE = 'codex_desktop_send_unavailable';
3
5
  export const DISABLED_BUILTIN_AGENT_TYPES = [
@@ -20,7 +22,9 @@ export function isAvailableBuiltinAgentType(value) {
20
22
  return AVAILABLE_BUILTIN_AGENT_TYPE_SET.has(value);
21
23
  }
22
24
  export function isAvailableAgentType(value) {
23
- return value.startsWith('custom:') || isAvailableBuiltinAgentType(value);
25
+ return value.startsWith('custom:')
26
+ || /^acp:[a-z0-9][a-z0-9._-]{0,63}$/.test(value)
27
+ || isAvailableBuiltinAgentType(value);
24
28
  }
25
29
  export function filterAvailableAgentTypes(values) {
26
30
  const filtered = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shennian",
3
- "version": "0.4.10",
3
+ "version": "0.4.13",
4
4
  "description": "Shennian — AI Agent Control Plane CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -37,12 +37,14 @@
37
37
  "node": ">=18"
38
38
  },
39
39
  "dependencies": {
40
+ "@agentclientprotocol/sdk": "1.4.0",
40
41
  "@sinclair/typebox": "^0.34.49",
41
42
  "chalk": "^5.4.1",
42
43
  "commander": "^13.1.0",
43
44
  "qrcode": "^1.5.4",
44
45
  "qrcode-terminal": "^0.12.0",
45
46
  "ws": "^8.18.1",
47
+ "zod": "3.25.76",
46
48
  "@shennian/wire": "0.1.5"
47
49
  },
48
50
  "devDependencies": {
@@ -55,8 +57,8 @@
55
57
  "typescript": "^5.9.3"
56
58
  },
57
59
  "scripts": {
58
- "build": "tsc && node scripts/copy-macos-background-client.mjs && node -e \"require('node:fs').chmodSync('dist/bin/shennian.js', 0o755)\"",
59
- "build:publish": "pnpm --filter @shennian/wire build:publish && node -e \"const fs=require('node:fs'); fs.rmSync('dist', { recursive: true, force: true }); fs.rmSync('.tsbuildinfo.publish', { force: true })\" && tsc -p tsconfig.publish.json && node scripts/copy-macos-background-client.mjs && node scripts/minify-publish-js.mjs && node -e \"require('node:fs').chmodSync('dist/bin/shennian.js', 0o755)\" && node scripts/check-publish-artifact.mjs",
60
+ "build": "node -e \"require('node:fs').rmSync('dist/native/macos-background-client', { recursive: true, force: true })\" && tsc && node -e \"require('node:fs').chmodSync('dist/bin/shennian.js', 0o755)\"",
61
+ "build:publish": "pnpm --filter @shennian/wire build:publish && node -e \"const fs=require('node:fs'); fs.rmSync('dist', { recursive: true, force: true }); fs.rmSync('.tsbuildinfo.publish', { force: true })\" && tsc -p tsconfig.publish.json && node scripts/minify-publish-js.mjs && node -e \"require('node:fs').chmodSync('dist/bin/shennian.js', 0o755)\" && node scripts/check-publish-artifact.mjs",
60
62
  "test:security:codex": "tsx scripts/verify-managed-codex-sandbox.ts",
61
63
  "test:security:codex-tools": "tsx scripts/verify-managed-codex-dynamic-tools.ts",
62
64
  "dev": "tsc --watch"
@@ -1,17 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>CFBundleDevelopmentRegion</key><string>en</string>
6
- <key>CFBundleDisplayName</key><string>Shennian</string>
7
- <key>CFBundleExecutable</key><string>ShennianClientLauncher</string>
8
- <key>CFBundleIdentifier</key><string>net.shennian.client.background-service</string>
9
- <key>CFBundleInfoDictionaryVersion</key><string>6.0</string>
10
- <key>CFBundleName</key><string>Shennian</string>
11
- <key>CFBundlePackageType</key><string>APPL</string>
12
- <key>CFBundleShortVersionString</key><string>1.0.0</string>
13
- <key>CFBundleVersion</key><string>1.0.0</string>
14
- <key>LSBackgroundOnly</key><true/>
15
- <key>LSMinimumSystemVersion</key><string>13.0</string>
16
- </dict>
17
- </plist>
@@ -1,2 +0,0 @@
1
- "CFBundleDisplayName" = "Shennian";
2
- "CFBundleName" = "Shennian";
@@ -1,2 +0,0 @@
1
- "CFBundleDisplayName" = "神念";
2
- "CFBundleName" = "神念";
@@ -1,153 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
- <plist version="1.0">
4
- <dict>
5
- <key>files</key>
6
- <dict>
7
- <key>Resources/en.lproj/InfoPlist.strings</key>
8
- <dict>
9
- <key>hash</key>
10
- <data>
11
- 7cZ/3Y+z3FLOqySef5/rGgdk+hU=
12
- </data>
13
- <key>optional</key>
14
- <true/>
15
- </dict>
16
- <key>Resources/zh-Hans.lproj/InfoPlist.strings</key>
17
- <dict>
18
- <key>hash</key>
19
- <data>
20
- 6MKN0tNN2Z8t8wIkKiANNKgscLY=
21
- </data>
22
- <key>optional</key>
23
- <true/>
24
- </dict>
25
- </dict>
26
- <key>files2</key>
27
- <dict>
28
- <key>Resources/en.lproj/InfoPlist.strings</key>
29
- <dict>
30
- <key>hash2</key>
31
- <data>
32
- FJaLoD8f3R/s4Tvbgbvcrb9uzFLfPBACRdeL+bpiUtw=
33
- </data>
34
- <key>optional</key>
35
- <true/>
36
- </dict>
37
- <key>Resources/zh-Hans.lproj/InfoPlist.strings</key>
38
- <dict>
39
- <key>hash2</key>
40
- <data>
41
- B/tCw00PlOTxARULQMz6SavBh8IU6/M0b8GXT253tC0=
42
- </data>
43
- <key>optional</key>
44
- <true/>
45
- </dict>
46
- </dict>
47
- <key>rules</key>
48
- <dict>
49
- <key>^Resources/</key>
50
- <true/>
51
- <key>^Resources/.*\.lproj/</key>
52
- <dict>
53
- <key>optional</key>
54
- <true/>
55
- <key>weight</key>
56
- <real>1000</real>
57
- </dict>
58
- <key>^Resources/.*\.lproj/locversion.plist$</key>
59
- <dict>
60
- <key>omit</key>
61
- <true/>
62
- <key>weight</key>
63
- <real>1100</real>
64
- </dict>
65
- <key>^Resources/Base\.lproj/</key>
66
- <dict>
67
- <key>weight</key>
68
- <real>1010</real>
69
- </dict>
70
- <key>^version.plist$</key>
71
- <true/>
72
- </dict>
73
- <key>rules2</key>
74
- <dict>
75
- <key>.*\.dSYM($|/)</key>
76
- <dict>
77
- <key>weight</key>
78
- <real>11</real>
79
- </dict>
80
- <key>^(.*/)?\.DS_Store$</key>
81
- <dict>
82
- <key>omit</key>
83
- <true/>
84
- <key>weight</key>
85
- <real>2000</real>
86
- </dict>
87
- <key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
88
- <dict>
89
- <key>nested</key>
90
- <true/>
91
- <key>weight</key>
92
- <real>10</real>
93
- </dict>
94
- <key>^.*</key>
95
- <true/>
96
- <key>^Info\.plist$</key>
97
- <dict>
98
- <key>omit</key>
99
- <true/>
100
- <key>weight</key>
101
- <real>20</real>
102
- </dict>
103
- <key>^PkgInfo$</key>
104
- <dict>
105
- <key>omit</key>
106
- <true/>
107
- <key>weight</key>
108
- <real>20</real>
109
- </dict>
110
- <key>^Resources/</key>
111
- <dict>
112
- <key>weight</key>
113
- <real>20</real>
114
- </dict>
115
- <key>^Resources/.*\.lproj/</key>
116
- <dict>
117
- <key>optional</key>
118
- <true/>
119
- <key>weight</key>
120
- <real>1000</real>
121
- </dict>
122
- <key>^Resources/.*\.lproj/locversion.plist$</key>
123
- <dict>
124
- <key>omit</key>
125
- <true/>
126
- <key>weight</key>
127
- <real>1100</real>
128
- </dict>
129
- <key>^Resources/Base\.lproj/</key>
130
- <dict>
131
- <key>weight</key>
132
- <real>1010</real>
133
- </dict>
134
- <key>^[^/]+$</key>
135
- <dict>
136
- <key>nested</key>
137
- <true/>
138
- <key>weight</key>
139
- <real>10</real>
140
- </dict>
141
- <key>^embedded\.provisionprofile$</key>
142
- <dict>
143
- <key>weight</key>
144
- <real>20</real>
145
- </dict>
146
- <key>^version\.plist$</key>
147
- <dict>
148
- <key>weight</key>
149
- <real>20</real>
150
- </dict>
151
- </dict>
152
- </dict>
153
- </plist>