appduct 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (230) hide show
  1. package/README.md +121 -51
  2. package/dist/artifact-inspect.d.ts +0 -1
  3. package/dist/bin.d.ts +0 -1
  4. package/dist/bin.js +1250 -2
  5. package/dist/cli/command-options.d.ts +8 -1
  6. package/dist/cli/create-cli.d.ts +0 -1
  7. package/dist/cli/dispatch.d.ts +10 -1
  8. package/dist/cli/envelope.d.ts +19 -0
  9. package/dist/cli/global-flags.d.ts +30 -0
  10. package/dist/cli/open-target.d.ts +25 -8
  11. package/dist/cli/result-types.d.ts +30 -5
  12. package/dist/cli/router.d.ts +78 -0
  13. package/dist/cli/routes/daemon/index.d.ts +9 -0
  14. package/dist/cli/routes/daemon/index.js +848 -0
  15. package/dist/cli/routes/daemon/run.d.ts +3 -0
  16. package/dist/cli/routes/daemon/run.js +3246 -0
  17. package/dist/cli/routes/daemon/start.d.ts +3 -0
  18. package/dist/cli/routes/daemon/start.js +1668 -0
  19. package/dist/cli/routes/daemon/status.d.ts +4 -0
  20. package/dist/cli/routes/daemon/status.js +1676 -0
  21. package/dist/cli/routes/daemon/stop.d.ts +4 -0
  22. package/dist/cli/routes/daemon/stop.js +1646 -0
  23. package/dist/cli/routes/doctor.d.ts +3 -0
  24. package/dist/cli/routes/doctor.js +1075 -0
  25. package/dist/cli/routes/events.d.ts +3 -0
  26. package/dist/cli/routes/events.js +1906 -0
  27. package/dist/cli/routes/init.d.ts +3 -0
  28. package/dist/cli/routes/init.js +1486 -0
  29. package/dist/cli/routes/invoke.d.ts +3 -0
  30. package/dist/cli/routes/invoke.js +1884 -0
  31. package/dist/cli/routes/keygen.d.ts +3 -0
  32. package/dist/cli/routes/keygen.js +928 -0
  33. package/dist/cli/routes/link.d.ts +3 -0
  34. package/dist/cli/routes/link.js +2705 -0
  35. package/dist/cli/routes/ls.d.ts +3 -0
  36. package/dist/cli/routes/ls.js +1659 -0
  37. package/dist/cli/routes/mcp.d.ts +5 -0
  38. package/dist/cli/routes/mcp.js +3917 -0
  39. package/dist/cli/routes/revoke.d.ts +3 -0
  40. package/dist/cli/routes/revoke.js +1675 -0
  41. package/dist/cli/routes/tools.d.ts +3 -0
  42. package/dist/cli/routes/tools.js +1851 -0
  43. package/dist/cli/runner.d.ts +3 -11
  44. package/dist/cli/types.d.ts +9 -6
  45. package/dist/cli/version-guard.d.ts +20 -0
  46. package/dist/cli.d.ts +0 -1
  47. package/dist/client/app-client.d.ts +0 -1
  48. package/dist/client/bootstrap.d.ts +4 -4
  49. package/dist/client/connect.d.ts +0 -1
  50. package/dist/client/errors.d.ts +0 -1
  51. package/dist/client/index.d.ts +0 -1
  52. package/dist/client/index.js +2379 -16
  53. package/dist/commands/daemon/context.d.ts +14 -0
  54. package/dist/commands/daemon/run.d.ts +11 -0
  55. package/dist/commands/daemon/start.d.ts +5 -0
  56. package/dist/commands/daemon/status.d.ts +5 -0
  57. package/dist/commands/daemon/stop.d.ts +5 -0
  58. package/dist/commands/doctor.d.ts +0 -1
  59. package/dist/commands/events.d.ts +0 -1
  60. package/dist/commands/init.d.ts +17 -4
  61. package/dist/commands/invoke.d.ts +0 -1
  62. package/dist/commands/keygen.d.ts +0 -1
  63. package/dist/commands/link.d.ts +1 -2
  64. package/dist/commands/ls.d.ts +0 -1
  65. package/dist/commands/mcp.d.ts +2 -4
  66. package/dist/commands/revoke.d.ts +0 -1
  67. package/dist/commands/tools.d.ts +19 -3
  68. package/dist/daemon/address.d.ts +0 -1
  69. package/dist/daemon/audit.d.ts +6 -11
  70. package/dist/daemon/calls.d.ts +0 -1
  71. package/dist/daemon/config.d.ts +13 -16
  72. package/dist/daemon/daemon.d.ts +0 -1
  73. package/dist/daemon/event-bus.d.ts +0 -1
  74. package/dist/daemon/links.d.ts +0 -1
  75. package/dist/daemon/listener.d.ts +0 -1
  76. package/dist/daemon/log-rotation.d.ts +0 -1
  77. package/dist/daemon/pidfile.d.ts +14 -8
  78. package/dist/daemon/policy.d.ts +0 -1
  79. package/dist/daemon/registry.d.ts +0 -1
  80. package/dist/daemon/rpc-errors.d.ts +16 -0
  81. package/dist/daemon/rpc-server.d.ts +0 -11
  82. package/dist/daemon/sessions.d.ts +0 -1
  83. package/dist/daemon/socket-probe.d.ts +0 -1
  84. package/dist/daemon/state-dir.d.ts +0 -1
  85. package/dist/daemon/timers.d.ts +0 -1
  86. package/dist/daemon/tls.d.ts +0 -1
  87. package/dist/errors.d.ts +0 -1
  88. package/dist/host-certificate.d.ts +0 -1
  89. package/dist/index.d.ts +0 -1
  90. package/dist/index.js +1307 -3
  91. package/dist/key-material.d.ts +0 -1
  92. package/dist/link.d.ts +8 -7
  93. package/dist/mcp/app-tools.d.ts +153 -0
  94. package/dist/mcp/connect-tool.d.ts +14 -8
  95. package/dist/mcp/daemon-tools.d.ts +2 -11
  96. package/dist/mcp/events-tool.d.ts +0 -1
  97. package/dist/mcp/server.d.ts +33 -14
  98. package/dist/native-scheme.d.ts +0 -1
  99. package/dist/output.d.ts +8 -11
  100. package/dist/package-root.d.ts +11 -0
  101. package/dist/package-version.d.ts +0 -1
  102. package/dist/qr-terminal.d.ts +0 -1
  103. package/dist/rpc/client.d.ts +0 -1
  104. package/dist/scheme.d.ts +60 -2
  105. package/dist/spki-pin.d.ts +0 -1
  106. package/package.json +4 -3
  107. package/dist/artifact-inspect.d.ts.map +0 -1
  108. package/dist/artifact-inspect.js +0 -334
  109. package/dist/bin.d.ts.map +0 -1
  110. package/dist/cli/command-options.d.ts.map +0 -1
  111. package/dist/cli/command-options.js +0 -95
  112. package/dist/cli/create-cli.d.ts.map +0 -1
  113. package/dist/cli/create-cli.js +0 -56
  114. package/dist/cli/dispatch.d.ts.map +0 -1
  115. package/dist/cli/dispatch.js +0 -275
  116. package/dist/cli/open-target.d.ts.map +0 -1
  117. package/dist/cli/open-target.js +0 -438
  118. package/dist/cli/result-types.d.ts.map +0 -1
  119. package/dist/cli/result-types.js +0 -6
  120. package/dist/cli/runner.d.ts.map +0 -1
  121. package/dist/cli/runner.js +0 -111
  122. package/dist/cli/types.d.ts.map +0 -1
  123. package/dist/cli/types.js +0 -10
  124. package/dist/cli.d.ts.map +0 -1
  125. package/dist/cli.js +0 -2
  126. package/dist/client/app-client.d.ts.map +0 -1
  127. package/dist/client/app-client.js +0 -223
  128. package/dist/client/bootstrap.d.ts.map +0 -1
  129. package/dist/client/bootstrap.js +0 -108
  130. package/dist/client/connect.d.ts.map +0 -1
  131. package/dist/client/connect.js +0 -38
  132. package/dist/client/errors.d.ts.map +0 -1
  133. package/dist/client/errors.js +0 -40
  134. package/dist/client/index.d.ts.map +0 -1
  135. package/dist/commands/daemon.d.ts +0 -22
  136. package/dist/commands/daemon.d.ts.map +0 -1
  137. package/dist/commands/daemon.js +0 -128
  138. package/dist/commands/doctor.d.ts.map +0 -1
  139. package/dist/commands/doctor.js +0 -42
  140. package/dist/commands/events.d.ts.map +0 -1
  141. package/dist/commands/events.js +0 -76
  142. package/dist/commands/init.d.ts.map +0 -1
  143. package/dist/commands/init.js +0 -231
  144. package/dist/commands/invoke.d.ts.map +0 -1
  145. package/dist/commands/invoke.js +0 -54
  146. package/dist/commands/keygen.d.ts.map +0 -1
  147. package/dist/commands/keygen.js +0 -46
  148. package/dist/commands/link.d.ts.map +0 -1
  149. package/dist/commands/link.js +0 -43
  150. package/dist/commands/ls.d.ts.map +0 -1
  151. package/dist/commands/ls.js +0 -7
  152. package/dist/commands/mcp.d.ts.map +0 -1
  153. package/dist/commands/mcp.js +0 -98
  154. package/dist/commands/revoke.d.ts.map +0 -1
  155. package/dist/commands/revoke.js +0 -7
  156. package/dist/commands/tools.d.ts.map +0 -1
  157. package/dist/commands/tools.js +0 -52
  158. package/dist/daemon/address.d.ts.map +0 -1
  159. package/dist/daemon/address.js +0 -71
  160. package/dist/daemon/audit.d.ts.map +0 -1
  161. package/dist/daemon/audit.js +0 -237
  162. package/dist/daemon/calls.d.ts.map +0 -1
  163. package/dist/daemon/calls.js +0 -158
  164. package/dist/daemon/config.d.ts.map +0 -1
  165. package/dist/daemon/config.js +0 -170
  166. package/dist/daemon/daemon.d.ts.map +0 -1
  167. package/dist/daemon/daemon.js +0 -560
  168. package/dist/daemon/event-bus.d.ts.map +0 -1
  169. package/dist/daemon/event-bus.js +0 -111
  170. package/dist/daemon/links.d.ts.map +0 -1
  171. package/dist/daemon/links.js +0 -118
  172. package/dist/daemon/listener.d.ts.map +0 -1
  173. package/dist/daemon/listener.js +0 -132
  174. package/dist/daemon/log-rotation.d.ts.map +0 -1
  175. package/dist/daemon/log-rotation.js +0 -136
  176. package/dist/daemon/pidfile.d.ts.map +0 -1
  177. package/dist/daemon/pidfile.js +0 -90
  178. package/dist/daemon/policy.d.ts.map +0 -1
  179. package/dist/daemon/policy.js +0 -24
  180. package/dist/daemon/registry.d.ts.map +0 -1
  181. package/dist/daemon/registry.js +0 -31
  182. package/dist/daemon/rpc-server.d.ts.map +0 -1
  183. package/dist/daemon/rpc-server.js +0 -203
  184. package/dist/daemon/sessions.d.ts.map +0 -1
  185. package/dist/daemon/sessions.js +0 -429
  186. package/dist/daemon/socket-probe.d.ts.map +0 -1
  187. package/dist/daemon/socket-probe.js +0 -28
  188. package/dist/daemon/state-dir.d.ts.map +0 -1
  189. package/dist/daemon/state-dir.js +0 -43
  190. package/dist/daemon/timers.d.ts.map +0 -1
  191. package/dist/daemon/timers.js +0 -12
  192. package/dist/daemon/tls.d.ts.map +0 -1
  193. package/dist/daemon/tls.js +0 -79
  194. package/dist/errors.d.ts.map +0 -1
  195. package/dist/errors.js +0 -162
  196. package/dist/host-certificate.d.ts.map +0 -1
  197. package/dist/host-certificate.js +0 -111
  198. package/dist/index.d.ts.map +0 -1
  199. package/dist/key-material.d.ts.map +0 -1
  200. package/dist/key-material.js +0 -42
  201. package/dist/link.d.ts.map +0 -1
  202. package/dist/link.js +0 -117
  203. package/dist/mcp/connect-tool.d.ts.map +0 -1
  204. package/dist/mcp/connect-tool.js +0 -396
  205. package/dist/mcp/daemon-tools.d.ts.map +0 -1
  206. package/dist/mcp/daemon-tools.js +0 -29
  207. package/dist/mcp/events-tool.d.ts.map +0 -1
  208. package/dist/mcp/events-tool.js +0 -322
  209. package/dist/mcp/server.d.ts.map +0 -1
  210. package/dist/mcp/server.js +0 -538
  211. package/dist/mcp/tool-mapping.d.ts +0 -58
  212. package/dist/mcp/tool-mapping.d.ts.map +0 -1
  213. package/dist/mcp/tool-mapping.js +0 -143
  214. package/dist/mcp/tool-namespace.d.ts +0 -40
  215. package/dist/mcp/tool-namespace.d.ts.map +0 -1
  216. package/dist/mcp/tool-namespace.js +0 -65
  217. package/dist/native-scheme.d.ts.map +0 -1
  218. package/dist/native-scheme.js +0 -465
  219. package/dist/output.d.ts.map +0 -1
  220. package/dist/output.js +0 -342
  221. package/dist/package-version.d.ts.map +0 -1
  222. package/dist/package-version.js +0 -47
  223. package/dist/qr-terminal.d.ts.map +0 -1
  224. package/dist/qr-terminal.js +0 -45
  225. package/dist/rpc/client.d.ts.map +0 -1
  226. package/dist/rpc/client.js +0 -819
  227. package/dist/scheme.d.ts.map +0 -1
  228. package/dist/scheme.js +0 -321
  229. package/dist/spki-pin.d.ts.map +0 -1
  230. package/dist/spki-pin.js +0 -14
package/dist/output.js DELETED
@@ -1,342 +0,0 @@
1
- import pc from "picocolors";
2
- import { formatAgentWebSocketUrl } from "@appduct/shared";
3
- import { renderQrToTerminal } from "./qr-terminal.js";
4
- const indentJson = (value) => {
5
- return JSON.stringify(value, null, 2);
6
- };
7
- const renderMetaLines = (meta) => {
8
- if (!meta) {
9
- return [];
10
- }
11
- return [
12
- "Meta",
13
- ` Command: ${meta.command}`,
14
- ` Timestamp: ${meta.timestamp}`,
15
- ...(typeof meta.duration_ms === "number" ? [` Duration: ${meta.duration_ms} ms`] : []),
16
- ];
17
- };
18
- const formatScalar = (value) => {
19
- if (typeof value === "string") {
20
- return value;
21
- }
22
- if (typeof value === "number" || typeof value === "boolean") {
23
- return String(value);
24
- }
25
- if (value === null || value === undefined) {
26
- return "null";
27
- }
28
- return indentJson(value);
29
- };
30
- const renderFields = (title, fields) => {
31
- const visibleFields = fields.filter(([, value]) => value !== undefined);
32
- if (visibleFields.length === 0) {
33
- return [];
34
- }
35
- const width = Math.max(...visibleFields.map(([label]) => label.length));
36
- return [
37
- title,
38
- ...visibleFields.map(([label, value]) => ` ${label.padEnd(width)} ${formatScalar(value)}`),
39
- ];
40
- };
41
- /** Humanizes an elapsed duration for `ls`'s "age" column: seconds/minutes/hours/days, coarsest unit
42
- * that keeps at least one digit of precision. */
43
- const formatAge = (fromIso, toIso) => {
44
- const elapsedMs = Math.max(0, new Date(toIso).getTime() - new Date(fromIso).getTime());
45
- const elapsedSeconds = Math.floor(elapsedMs / 1000);
46
- if (elapsedSeconds < 60) {
47
- return `${elapsedSeconds}s`;
48
- }
49
- const elapsedMinutes = Math.floor(elapsedSeconds / 60);
50
- if (elapsedMinutes < 60) {
51
- return `${elapsedMinutes}m`;
52
- }
53
- const elapsedHours = Math.floor(elapsedMinutes / 60);
54
- if (elapsedHours < 24) {
55
- return `${elapsedHours}h`;
56
- }
57
- return `${Math.floor(elapsedHours / 24)}d`;
58
- };
59
- const formatDevice = (device) => {
60
- const parts = [device.manufacturer, device.model].filter((part) => Boolean(part));
61
- const label = parts.length > 0 ? parts.join(" ") : "unknown device";
62
- return device.os ? `${label} (${device.os})` : label;
63
- };
64
- const renderLsData = (colors, data, meta) => {
65
- if (data.length === 0) {
66
- return [colors.dim("Sessions"), " No Appduct sessions are registered."];
67
- }
68
- const now = meta?.timestamp ?? new Date().toISOString();
69
- const headers = ["Alias", "State", "Device", "Tools", "Age"];
70
- const rows = data.map((session) => [
71
- session.alias,
72
- session.state,
73
- formatDevice(session.device),
74
- String(session.toolCount),
75
- formatAge(session.claimedAt ?? session.createdAt, now),
76
- ]);
77
- const widths = headers.map((header, index) => Math.max(header.length, ...rows.map((row) => row[index].length)));
78
- return [
79
- colors.green("Sessions"),
80
- ` ${headers.map((header, index) => header.padEnd(widths[index])).join(" ")}`,
81
- ...rows.map((row) => ` ${row.map((cell, index) => cell.padEnd(widths[index])).join(" ")}`),
82
- ];
83
- };
84
- const renderToolSummaryTable = (tools) => {
85
- if (tools.length === 0) {
86
- return ["Tools", " No tools registered."];
87
- }
88
- const nameWidth = Math.max(...tools.map((tool) => tool.name.length), "Name".length);
89
- return [
90
- "Tools",
91
- ` ${"Name".padEnd(nameWidth)} Description`,
92
- ...tools.map((tool) => ` ${tool.name.padEnd(nameWidth)} ${tool.description}`),
93
- ];
94
- };
95
- const renderToolDetail = (colors, tool) => {
96
- return renderFields(colors.green(`Tool: ${tool.name}`), [
97
- ["Description", tool.description],
98
- ["Input schema", tool.input_schema],
99
- ["Output schema", tool.output_schema],
100
- ["Annotations", tool.annotations],
101
- // Only rendered for a tool that declares one; `renderFields` drops undefined rows, so a tool
102
- // on the daemon's default deadline shows no line at all rather than a misleading "10000".
103
- ["Timeout (ms)", tool.timeout_ms],
104
- ]);
105
- };
106
- const renderToolsData = (colors, data, full) => {
107
- if (!Array.isArray(data)) {
108
- return renderToolDetail(colors, data);
109
- }
110
- if (full) {
111
- return data.length === 0
112
- ? ["Tools", " No tools registered."]
113
- : data.flatMap((tool, index) => [...(index > 0 ? [""] : []), ...renderToolDetail(colors, tool)]);
114
- }
115
- return [colors.green("Tools"), ...renderToolSummaryTable(data).slice(1)];
116
- };
117
- const renderInvokeData = (colors, data) => {
118
- return [colors.green("Result"), formatScalar(data)];
119
- };
120
- const renderLinkData = (colors, data, qr) => {
121
- const lines = [
122
- colors.green("Link Created"),
123
- ...renderFields("Link", [
124
- ["Session", data.sessionId],
125
- ["Deep link", data.deepLink],
126
- ["Endpoint", formatAgentWebSocketUrl(data.endpoint)],
127
- ["Pin", data.pin],
128
- ["Expires", new Date(data.expiresAt * 1000).toISOString()],
129
- ["Delivered", data.delivered ? `yes (${data.target})` : undefined],
130
- ]),
131
- ];
132
- if (qr) {
133
- lines.push("", "QR", renderQrToTerminal(data.deepLink));
134
- }
135
- return lines;
136
- };
137
- const renderRevokeData = (colors, _data) => {
138
- return [colors.green("Session Revoked")];
139
- };
140
- const renderKeygenData = (colors, data) => {
141
- return [
142
- colors.green("Key Ready"),
143
- ...renderFields("Key", [
144
- ["Path", data.path],
145
- ["Fingerprint", data.pin],
146
- ]),
147
- ];
148
- };
149
- const renderInitData = (colors, data) => {
150
- const snippet = JSON.stringify({ mcpServers: { appduct: data.mcpServerEntry } }, null, 2);
151
- return [
152
- colors.green(data.changed ? "Project Initialized" : "Project Already Initialized"),
153
- ...renderFields("Config", [
154
- ["Path", data.path],
155
- ["Scheme", data.scheme],
156
- ["Source", data.source],
157
- // Only present for a scheme discovery read off a static project file (app.json, or one of
158
- // the native Android/iOS probes) — names the exact file/key, not just which platform.
159
- ["Read from", data.origin],
160
- ["Written", data.changed ? (data.created ? "created" : "updated") : "unchanged"],
161
- ]),
162
- ...(data.note === undefined ? [] : ["", colors.yellow(`Note: ${data.note}`)]),
163
- "",
164
- "MCP server entry",
165
- ...snippet.split("\n").map((line) => ` ${line}`),
166
- "",
167
- "Next",
168
- ...data.nextSteps.map((step, index) => ` ${index + 1}. ${step}`),
169
- ];
170
- };
171
- const renderDaemonRunData = (colors, data) => {
172
- return [
173
- colors.green("Daemon Running"),
174
- ...renderFields("Daemon", [
175
- ["PID", data.daemon.pid],
176
- ["State dir", data.daemon.state_dir],
177
- ["Socket", data.daemon.socket_path],
178
- ]),
179
- ];
180
- };
181
- const renderDaemonStartData = (colors, data) => {
182
- return [
183
- colors.green("Daemon Started"),
184
- ...renderFields("Daemon", [
185
- ["PID", data.daemon.pid],
186
- ["WSS port", data.daemon.wss_port],
187
- ["Started at", data.daemon.started_at],
188
- ]),
189
- ];
190
- };
191
- const renderDaemonStopData = (colors, data) => {
192
- return [
193
- colors.green("Daemon Stopped"),
194
- ...renderFields("Daemon", [["Method", data.daemon.method]]),
195
- ];
196
- };
197
- /** Human column for a byte count (the machine-readable `bytes` stays exact in `--json`). Binary
198
- * units, one decimal above KiB, so a growing `audit/` reads at a glance. */
199
- const formatByteSize = (bytes) => {
200
- const units = ["B", "KiB", "MiB", "GiB", "TiB"];
201
- let value = bytes;
202
- let unit = 0;
203
- while (value >= 1024 && unit < units.length - 1) {
204
- value /= 1024;
205
- unit += 1;
206
- }
207
- return `${unit === 0 ? value : value.toFixed(1)} ${units[unit]}`;
208
- };
209
- const renderDaemonStatusData = (colors, data) => {
210
- return [
211
- colors.green("Daemon Status"),
212
- ...renderFields("Daemon", [
213
- ["Version", data.daemon.version],
214
- ["PID", data.daemon.pid],
215
- ["Started at", data.daemon.started_at],
216
- ["WSS port", data.daemon.wss_port],
217
- ["Pinned keys", data.daemon.pinned_keys.length],
218
- ["Sessions", data.daemon.session_count],
219
- ]),
220
- "",
221
- ...renderFields("Policy", [
222
- ["Default", data.policy.default],
223
- ["Destructive", data.policy.destructive],
224
- ["Overrides", data.policy.tools ? Object.keys(data.policy.tools).length : 0],
225
- ]),
226
- "",
227
- // The retention rows drop out entirely against a daemon that predates them (`renderFields`
228
- // skips `undefined`), rather than printing "undefined" or an invented zero.
229
- ...renderFields("Audit", [
230
- ["Path", data.audit.path],
231
- ["Retention", data.audit.retention_days === undefined ? undefined : `${data.audit.retention_days} days`],
232
- ["Files", data.audit.files],
233
- ["Size", data.audit.bytes === undefined ? undefined : formatByteSize(data.audit.bytes)],
234
- ["Failed writes", data.audit.failed_writes],
235
- ["Failed prunes", data.audit.failed_prunes],
236
- ]),
237
- // Version drift (issue #30) is the one thing here an operator has to act on, so it goes last
238
- // — the line still on screen after the block scrolls — and in yellow, not a quiet field row.
239
- ...(data.warning ? ["", colors.yellow(`Warning: ${data.warning}`)] : []),
240
- ];
241
- };
242
- const renderDoctorData = (colors, data) => {
243
- return [
244
- data.present ? colors.green("Appduct Present") : colors.yellow("Appduct Absent"),
245
- ...renderFields("Artifact", [
246
- ["Path", data.artifact],
247
- ["Platform", data.platform],
248
- ["Format", data.format],
249
- ["Present", data.present],
250
- ["Signals", data.signals.length > 0 ? data.signals.join(", ") : "none"],
251
- ["Assertion", data.assertion ? `${data.assertion.expected} (holds)` : undefined],
252
- ]),
253
- ];
254
- };
255
- const renderSuccessData = (colors, command, data, options, meta) => {
256
- switch (command) {
257
- case "init":
258
- return renderInitData(colors, data);
259
- case "keygen":
260
- return renderKeygenData(colors, data);
261
- case "link":
262
- return renderLinkData(colors, data, options.qr);
263
- case "ls":
264
- return renderLsData(colors, data, meta);
265
- case "tools":
266
- return renderToolsData(colors, data, options.full);
267
- case "invoke":
268
- return renderInvokeData(colors, data);
269
- case "revoke":
270
- return renderRevokeData(colors, data);
271
- case "daemon run":
272
- return renderDaemonRunData(colors, data);
273
- case "daemon start":
274
- return renderDaemonStartData(colors, data);
275
- case "daemon stop":
276
- return renderDaemonStopData(colors, data);
277
- case "daemon status":
278
- return renderDaemonStatusData(colors, data);
279
- case "doctor":
280
- return renderDoctorData(colors, data);
281
- default:
282
- return [colors.green("Command Complete"), indentJson(data)];
283
- }
284
- };
285
- const renderHumanError = (colors, error, meta) => {
286
- return [
287
- colors.red("Command Failed"),
288
- ...renderFields("Error", [
289
- ["Type", error.type],
290
- ["Message", error.message],
291
- ["Details", error.details],
292
- ]),
293
- ...(meta ? ["", ...renderMetaLines(meta)] : []),
294
- ].join("\n");
295
- };
296
- export const renderResult = (result, options) => {
297
- if (options.json) {
298
- return {
299
- stdout: `${indentJson(result)}\n`,
300
- };
301
- }
302
- const colors = pc.createColors(options.color);
303
- if (!result.ok) {
304
- return {
305
- stderr: `${renderHumanError(colors, result.error, result.meta)}\n`,
306
- };
307
- }
308
- const lines = [
309
- ...renderSuccessData(colors, options.command, result.data, options, result.meta),
310
- "",
311
- ...renderMetaLines(result.meta),
312
- ].filter((line, index, collection) => {
313
- if (line !== "") {
314
- return true;
315
- }
316
- return index > 0 && collection[index - 1] !== "" && index < collection.length - 1;
317
- });
318
- return {
319
- stdout: `${lines.join("\n")}\n`,
320
- };
321
- };
322
- /** Renders one `appduct events` line: NDJSON under `--json`, a compact human line otherwise. */
323
- export const renderEventLine = (event, options) => {
324
- if (options.json) {
325
- return JSON.stringify(event);
326
- }
327
- const colors = pc.createColors(options.color);
328
- const timestamp = new Date(event.ts).toISOString();
329
- const target = event.alias ?? event.sessionId;
330
- const dataSuffix = event.data === undefined ? "" : ` ${indentJson(event.data)}`;
331
- return `${colors.dim(timestamp)} ${colors.green(event.kind)}${target ? ` ${target}` : ""}${dataSuffix}`;
332
- };
333
- /** Renders the trailing cursor line for `appduct events --since` (issue #6): NDJSON under
334
- * `--json` so a scripted caller can parse the resume point without maxing `seq` over the printed
335
- * events (impossible when the response is empty), a human note otherwise. */
336
- export const renderEventsCursorLine = (cursor, options) => {
337
- if (options.json) {
338
- return JSON.stringify({ cursor });
339
- }
340
- const colors = pc.createColors(options.color);
341
- return colors.dim(`cursor: ${cursor} (pass --since ${cursor} to resume from here)`);
342
- };
@@ -1 +0,0 @@
1
- {"version":3,"file":"package-version.d.ts","sourceRoot":"","sources":["../src/package-version.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,2BAA2B,oCAAoC,CAAC;AAW7E,mFAAmF;AACnF,eAAO,MAAM,iBAAiB,QAAO,MAGpC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GAAI,MAAK,MAAM,CAAC,UAAwB,KAAG,MAO/E,CAAC"}
@@ -1,47 +0,0 @@
1
- /**
2
- * The single source of truth for "what version of Appduct is this process running".
3
- *
4
- * The daemon (`daemon/daemon.ts`), the MCP server (`mcp/server.ts`), the CLI's `--version`
5
- * (`cli/create-cli.ts`) and the CLI's daemon version check (`cli/dispatch.ts`) all need the
6
- * published package version, and every one of them used to re-read `package.json` itself. They
7
- * read it through this module instead so a single mismatch in the relative path can't make one of
8
- * them report a different version than the others (issue #30).
9
- */
10
- import { readFileSync } from "node:fs";
11
- import { dirname, join } from "node:path";
12
- import { fileURLToPath } from "node:url";
13
- /**
14
- * Test seam (issue #30): when set, the daemon reports this instead of the real package version in
15
- * `daemon.status` and the `daemon_started` event, so an integration test can produce a genuine
16
- * client/daemon version mismatch without installing two builds. Read only by the daemon — a
17
- * *client* must always report the version it truly is, or the check would compare a lie to a lie.
18
- *
19
- * Honored **only under a test runner** (see {@link isTestRuntime}). A daemon that lied about its
20
- * version in production would make every command restart it, forever: the value is inherited by
21
- * whatever the shell exported, and the replacement daemon would report the same lie. The RPC
22
- * client additionally strips this key from the environment of any daemon it spawns.
23
- */
24
- export const DAEMON_VERSION_OVERRIDE_ENV = "APPDUCT_DAEMON_VERSION_OVERRIDE";
25
- /** True under Vitest, or with an explicit `NODE_ENV=test`. */
26
- const isTestRuntime = (env) => {
27
- return Boolean(env.VITEST) || env.NODE_ENV === "test";
28
- };
29
- const packageJsonPath = join(dirname(fileURLToPath(import.meta.url)), "..", "package.json");
30
- let cached;
31
- /** The `version` field of this package's `package.json`, read once per process. */
32
- export const getPackageVersion = () => {
33
- cached ??= JSON.parse(readFileSync(packageJsonPath, "utf8")).version;
34
- return cached;
35
- };
36
- /**
37
- * The version the *daemon* reports over RPC: {@link getPackageVersion}, unless
38
- * {@link DAEMON_VERSION_OVERRIDE_ENV} overrides it. Evaluated per call (not cached) so a daemon
39
- * started in-process by a test picks up the environment that test set.
40
- */
41
- export const getDaemonReportedVersion = (env = process.env) => {
42
- if (!isTestRuntime(env)) {
43
- return getPackageVersion();
44
- }
45
- const override = env[DAEMON_VERSION_OVERRIDE_ENV];
46
- return override !== undefined && override.length > 0 ? override : getPackageVersion();
47
- };
@@ -1 +0,0 @@
1
- {"version":3,"file":"qr-terminal.d.ts","sourceRoot":"","sources":["../src/qr-terminal.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,uBAAuB,GAAG;IACpC,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAMF;;GAEG;AACH,eAAO,MAAM,kBAAkB,GAC7B,SAAS,MAAM,EACf,UAAU,uBAAuB,KAChC,MAyCF,CAAC"}
@@ -1,45 +0,0 @@
1
- import { toQR } from "toqr";
2
- const HALF_UPPER = "\u2580"; // ▀
3
- const HALF_LOWER = "\u2584"; // ▄
4
- const FULL = "\u2588"; // █
5
- /**
6
- * Renders a QR payload as compact half-block terminal art (two modules per character row).
7
- */
8
- export const renderQrToTerminal = (content, options) => {
9
- const margin = options?.margin ?? 0;
10
- const ecLevel = options?.ecLevel ?? 1;
11
- const modules = toQR(content, ecLevel);
12
- const side = Math.sqrt(modules.length);
13
- if (!Number.isInteger(side)) {
14
- throw new Error("Invalid QR matrix size");
15
- }
16
- const dim = side + 2 * margin;
17
- const isDark = (row, col) => {
18
- if (row < margin ||
19
- col < margin ||
20
- row >= margin + side ||
21
- col >= margin + side) {
22
- return false;
23
- }
24
- const mr = row - margin;
25
- const mc = col - margin;
26
- return modules[mr * side + mc] === 1;
27
- };
28
- const lines = [];
29
- for (let row = 0; row < dim; row += 2) {
30
- let line = "";
31
- for (let col = 0; col < dim; col++) {
32
- const top = isDark(row, col);
33
- const bottom = row + 1 < dim ? isDark(row + 1, col) : false;
34
- line += top
35
- ? bottom
36
- ? FULL
37
- : HALF_UPPER
38
- : bottom
39
- ? HALF_LOWER
40
- : " ";
41
- }
42
- lines.push(line);
43
- }
44
- return lines.join("\n");
45
- };
@@ -1 +0,0 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/rpc/client.ts"],"names":[],"mappings":"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"}