tinker-agent 2.12.0 → 3.0.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 (61) hide show
  1. package/CHANGELOG.md +66 -1
  2. package/README.md +25 -4
  3. package/package.json +2 -1
  4. package/src/agent/runtime-hosted-session.ts +505 -81
  5. package/src/agent/runtime-session-contracts.ts +9 -0
  6. package/src/agent/runtime-session.ts +29 -7
  7. package/src/cli/command-line.ts +159 -11
  8. package/src/cli/connect-runner.tsx +63 -0
  9. package/src/cli/connect-workspace.ts +33 -0
  10. package/src/cli/default-service-config.ts +163 -0
  11. package/src/cli/default-tui-runner.ts +23 -0
  12. package/src/cli/interactive-runtime.ts +87 -0
  13. package/src/cli/local-service-start.ts +131 -0
  14. package/src/cli/local-tui-client.ts +234 -0
  15. package/src/cli/main.ts +46 -3
  16. package/src/cli/public-cli-contract.ts +65 -2
  17. package/src/cli/public-config-contract.ts +1 -1
  18. package/src/cli/runner-dependencies.ts +35 -35
  19. package/src/cli/serve-runner.ts +155 -21
  20. package/src/cli/serve-runtime.ts +47 -46
  21. package/src/cli/service-control.ts +27 -0
  22. package/src/cli/service-supervisor.ts +170 -0
  23. package/src/cli/service-upgrade.ts +106 -0
  24. package/src/cli/tui-runner.tsx +9 -261
  25. package/src/cli/update-runner.ts +4 -0
  26. package/src/client/local-workspace-client.ts +238 -0
  27. package/src/client/model-catalog.ts +15 -0
  28. package/src/client/remote-images.ts +80 -0
  29. package/src/client/remote-prompt-history.ts +22 -0
  30. package/src/client/remote-tasks.ts +231 -0
  31. package/src/client/remote-tui-view.ts +69 -0
  32. package/src/client/remote-workspace-client.ts +528 -0
  33. package/src/client/session-client.ts +109 -0
  34. package/src/image/image-asset-store.ts +17 -0
  35. package/src/remote/client.ts +27 -5
  36. package/src/remote/config.ts +19 -4
  37. package/src/remote/failures.ts +68 -0
  38. package/src/remote/http-server.ts +120 -3
  39. package/src/remote/local-service-discovery.ts +361 -0
  40. package/src/remote/prompt-history.ts +36 -0
  41. package/src/remote/protocol.ts +93 -2
  42. package/src/remote/resident-policy.ts +96 -0
  43. package/src/remote/service-store.ts +28 -6
  44. package/src/remote/service.ts +479 -60
  45. package/src/remote/session-operations.ts +66 -0
  46. package/src/remote/session-reads.ts +126 -0
  47. package/src/remote/sync-hub.ts +2 -0
  48. package/src/remote/tui-protocol.ts +32 -0
  49. package/src/remote/workspace-resolution.ts +82 -0
  50. package/src/session/resume-projection.ts +19 -2
  51. package/src/session/session-lock.ts +32 -0
  52. package/src/session/session-store-contracts.ts +2 -0
  53. package/src/session/session-store.ts +7 -4
  54. package/src/tools/bash.ts +9 -1
  55. package/src/tools/bounded-output-preview.ts +2 -2
  56. package/src/tui/app.tsx +67 -26
  57. package/src/tui/components/model-picker.tsx +5 -5
  58. package/src/tui/components/prompt-input.tsx +16 -1
  59. package/src/tui/components/resume-session-picker.tsx +6 -2
  60. package/src/tui/tui-projection-store.ts +25 -0
  61. package/src/tui/tui-session-controller.ts +12 -282
@@ -1,6 +1,7 @@
1
1
  import { Database } from "bun:sqlite";
2
2
  import { chmod, mkdir } from "node:fs/promises";
3
3
  import path from "node:path";
4
+ import type { RemoteWorkspaceConfig } from "./config";
4
5
  import { stableJsonStringify, sha256 } from "../model/model-request-preflight";
5
6
  import { parseSessionId } from "../ids/runtime-id";
6
7
  import { SessionLease } from "../session/session-lock";
@@ -14,6 +15,8 @@ import {
14
15
  export type ManagedSessionRecord = RemoteSessionInfo & {
15
16
  workspacePath: string;
16
17
  initialized: boolean;
18
+ profileName?: string;
19
+ residentState?: { reasoning?: string; yolo?: boolean };
17
20
  };
18
21
  type ReceiptRow = {
19
22
  device: string;
@@ -21,7 +24,7 @@ type ReceiptRow = {
21
24
  receipt: string;
22
25
  input: string;
23
26
  };
24
- const SERVICE_LEASE_ID = parseSessionId("00000000-0000-7000-8000-000000000001");
27
+ export const SERVICE_LEASE_ID = parseSessionId("00000000-0000-7000-8000-000000000001");
25
28
 
26
29
  /** Durable acceptance receipts, separate from the canonical conversation databases. */
27
30
  export class RemoteServiceStore {
@@ -48,12 +51,13 @@ export class RemoteServiceStore {
48
51
  const version = (
49
52
  db.query("PRAGMA user_version").get() as { user_version: number }
50
53
  ).user_version;
51
- if (version !== 0 && version !== 1)
54
+ if (version !== 0 && version !== 1 && version !== 2)
52
55
  throw new Error("Unsupported remote state schema.");
53
56
  db.exec(`CREATE TABLE IF NOT EXISTS managed_sessions (id TEXT PRIMARY KEY, record TEXT NOT NULL) STRICT;
54
57
  CREATE TABLE IF NOT EXISTS operations (id TEXT PRIMARY KEY, session_id TEXT NOT NULL, device TEXT NOT NULL, fingerprint TEXT NOT NULL, input TEXT NOT NULL, receipt TEXT NOT NULL) STRICT;
55
58
  CREATE INDEX IF NOT EXISTS operations_session ON operations(session_id);
56
- PRAGMA user_version=1;`);
59
+ CREATE TABLE IF NOT EXISTS registered_workspaces (id TEXT PRIMARY KEY, path TEXT NOT NULL UNIQUE, record TEXT NOT NULL) STRICT;
60
+ PRAGMA user_version=2;`);
57
61
  const store = new RemoteServiceStore(db, lease);
58
62
  for (const row of db.query("SELECT receipt FROM operations").all() as {
59
63
  receipt: string;
@@ -81,6 +85,18 @@ export class RemoteServiceStore {
81
85
  this.db.query("SELECT record FROM managed_sessions").all() as { record: string }[]
82
86
  ).map((row) => JSON.parse(row.record) as ManagedSessionRecord);
83
87
  }
88
+ workspaces(): RemoteWorkspaceConfig[] {
89
+ return (
90
+ this.db.query("SELECT record FROM registered_workspaces ORDER BY id").all() as {
91
+ record: string;
92
+ }[]
93
+ ).map((row) => JSON.parse(row.record) as RemoteWorkspaceConfig);
94
+ }
95
+ registerWorkspace(workspace: RemoteWorkspaceConfig): void {
96
+ this.db
97
+ .query("INSERT INTO registered_workspaces (id, path, record) VALUES (?, ?, ?)")
98
+ .run(workspace.id, workspace.path, JSON.stringify(workspace));
99
+ }
84
100
  session(id: string): ManagedSessionRecord | undefined {
85
101
  const row = this.db
86
102
  .query("SELECT record FROM managed_sessions WHERE id = ?")
@@ -94,6 +110,9 @@ export class RemoteServiceStore {
94
110
  )
95
111
  .run(record.id, JSON.stringify(record));
96
112
  }
113
+ releaseSession(id: string): void {
114
+ this.db.query("DELETE FROM managed_sessions WHERE id = ?").run(id);
115
+ }
97
116
  existing(input: RemoteOperationInput, device: string): OperationReceipt | undefined {
98
117
  const row = this.db
99
118
  .query("SELECT * FROM operations WHERE id = ?")
@@ -121,7 +140,9 @@ export class RemoteServiceStore {
121
140
  status: "accepted",
122
141
  createdAt: now,
123
142
  updatedAt: now,
124
- ...(input.kind === "prompt" ? { prompt: input.prompt } : {}),
143
+ ...(input.kind === "prompt"
144
+ ? { prompt: input.prompt, attachments: input.attachments }
145
+ : {}),
125
146
  };
126
147
  this.db.transaction(() => {
127
148
  this.db
@@ -150,11 +171,12 @@ export class RemoteServiceStore {
150
171
  );
151
172
  return JSON.parse(row.receipt) as OperationReceipt;
152
173
  }
153
- operations(sessionId: string): OperationReceipt[] {
174
+ operations(sessionId: string, includeResults = true): OperationReceipt[] {
154
175
  return (
155
176
  this.db
156
177
  .query(
157
- "SELECT receipt FROM operations WHERE session_id = ? ORDER BY rowid DESC LIMIT 100",
178
+ `SELECT ${includeResults ? "receipt" : "json_remove(receipt, '$.result', '$.sessionResult') AS receipt"}
179
+ FROM operations WHERE session_id = ? ORDER BY rowid DESC LIMIT 100`,
158
180
  )
159
181
  .all(sessionId) as { receipt: string }[]
160
182
  )