@intentic/sandbox-contract 1.235.0 → 1.237.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 (68) hide show
  1. package/dist/chores/chores.d.ts.map +1 -1
  2. package/dist/chores/chores.js +2 -1
  3. package/dist/chores/chores.js.map +1 -1
  4. package/dist/chores/index.d.ts +1 -0
  5. package/dist/chores/index.d.ts.map +1 -1
  6. package/dist/chores/index.js +1 -0
  7. package/dist/chores/index.js.map +1 -1
  8. package/dist/chores/probes.d.ts.map +1 -1
  9. package/dist/chores/probes.js +4 -3
  10. package/dist/chores/probes.js.map +1 -1
  11. package/dist/chores/workspace-scope.d.ts +4 -0
  12. package/dist/chores/workspace-scope.d.ts.map +1 -0
  13. package/dist/chores/workspace-scope.js +4 -0
  14. package/dist/chores/workspace-scope.js.map +1 -0
  15. package/dist/contracts/agent.contract.d.ts +2 -0
  16. package/dist/contracts/agent.contract.d.ts.map +1 -1
  17. package/dist/contracts/agents.contract.d.ts +6 -0
  18. package/dist/contracts/agents.contract.d.ts.map +1 -1
  19. package/dist/contracts/extensions.contract.d.ts +1 -2
  20. package/dist/contracts/extensions.contract.d.ts.map +1 -1
  21. package/dist/contracts/extensions.contract.js +5 -5
  22. package/dist/contracts/extensions.contract.js.map +1 -1
  23. package/dist/contracts/runner.contract.d.ts +2 -0
  24. package/dist/contracts/runner.contract.d.ts.map +1 -1
  25. package/dist/contracts/workspace.contract.d.ts +1 -0
  26. package/dist/contracts/workspace.contract.d.ts.map +1 -1
  27. package/dist/contracts/workspace.contract.js +2 -2
  28. package/dist/contracts/workspace.contract.js.map +1 -1
  29. package/dist/events.d.ts +8 -0
  30. package/dist/events.d.ts.map +1 -1
  31. package/dist/events.js +12 -2
  32. package/dist/events.js.map +1 -1
  33. package/dist/index.d.ts +10 -2
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/ingress-contract.d.ts.map +1 -1
  36. package/dist/ingress-contract.js.map +1 -1
  37. package/dist/ingress-protocol.d.ts +16 -0
  38. package/dist/ingress-protocol.d.ts.map +1 -0
  39. package/dist/ingress-protocol.js +263 -0
  40. package/dist/ingress-protocol.js.map +1 -0
  41. package/dist/schemas/agents.d.ts.map +1 -1
  42. package/dist/schemas/agents.js +5 -5
  43. package/dist/schemas/agents.js.map +1 -1
  44. package/dist/schemas/extension-updates.d.ts +2 -3
  45. package/dist/schemas/extension-updates.d.ts.map +1 -1
  46. package/dist/schemas/extension-updates.js +4 -3
  47. package/dist/schemas/extension-updates.js.map +1 -1
  48. package/dist/schemas/workspace-tree.d.ts +1 -0
  49. package/dist/schemas/workspace-tree.d.ts.map +1 -1
  50. package/dist/schemas/workspace-tree.js +8 -1
  51. package/dist/schemas/workspace-tree.js.map +1 -1
  52. package/package.json +4 -4
  53. package/src/chores/chores.ts +2 -1
  54. package/src/chores/index.ts +1 -0
  55. package/src/chores/probes.test.ts +12 -0
  56. package/src/chores/probes.ts +5 -3
  57. package/src/chores/workspace-scope.ts +12 -0
  58. package/src/contracts/extensions.contract.ts +7 -6
  59. package/src/contracts/workspace.contract.ts +3 -2
  60. package/src/events.ts +35 -4
  61. package/src/hostnames.ts +2 -2
  62. package/src/ingress-contract.ts +4 -2
  63. package/src/ingress-protocol.test.ts +509 -0
  64. package/src/ingress-protocol.ts +574 -0
  65. package/src/schemas/agents.ts +20 -21
  66. package/src/schemas/extension-updates.ts +9 -7
  67. package/src/schemas/workspace-tree.ts +13 -4
  68. package/src/tunnel-ids.ts +4 -4
@@ -701,11 +701,11 @@ export const LandConflictPathSchema = z.object({
701
701
  "Why it would not merge, and the three have nothing in common but the symptom. Your own uncommitted edits on that path, where yours is the copy at risk. The shared tree having moved under the conversation since it started, where nothing of yours is at risk. Or a file git cannot merge at all, where no automatic answer exists.",
702
702
  ),
703
703
  });
704
- /* land's outcome, per repo of the composition. `paths` is the set that genuinely failed to apply. NOT the
704
+ /* A composed land's refusal, grouped per repo. `paths` is the set that genuinely failed to apply. NOT the
705
705
  * whole delta, which is what the first version reported whenever it could not pin the cause down, turning
706
- * four real conflicts into a wall of fourteen. `clean` counts what would land regardless, so the UI can say
707
- * how much is being held back by how little, and offer to take it. An empty `paths` with `clean: 0` is the
708
- * repo-unavailable case: the main checkout is gone, and no path-level account exists. */
706
+ * four real conflicts into a wall of fourteen. `clean` counts what passed in that repo but stays on the branch
707
+ * with the rest of the composition. An empty `paths` with `clean: 0` is the repo-unavailable case: the main
708
+ * checkout is gone, and no path-level account exists. */
709
709
  export const LandConflictSchema = z.object({
710
710
  repo: z.string().describe("Which repository."),
711
711
  paths: z
@@ -716,7 +716,7 @@ export const LandConflictSchema = z.object({
716
716
  clean: z
717
717
  .number()
718
718
  .describe(
719
- "How many files would apply regardless, so a screen can say how much is being held back by how little and offer to take it. Zero alongside an empty list means the repository could not be reached at all.",
719
+ "How many files in this repository passed but remain held with the refused composition. Zero alongside an empty list means the repository could not be reached at all.",
720
720
  ),
721
721
  // The branch the user's checkout is on, the thing the agent has to rebase onto. Carried because only the
722
722
  // daemon can see it: an isolated turn's worktree is mounted over the agent's whole view, so the resolution
@@ -730,13 +730,13 @@ export const LandConflictSchema = z.object({
730
730
  ),
731
731
  });
732
732
  export type LandConflict = z.infer<typeof LandConflictSchema>;
733
- // land's outcome; landed only when every repo with changes applied cleanly. Conflicted repos keep their
734
- // worktree state, nothing is lost, and "Land now" stays available. `resolving` is populated only by a
735
- // `merge` land: the paths written into the workspace carrying conflict markers, which the user finishes by
736
- // hand in their own editor exactly as they would any merge.
733
+ // Land's outcome for the whole frozen repo composition. The ordinary mode preflights every repo before it
734
+ // writes any main tree: landed means all of them applied, and a conflict means none did. Every worktree keeps
735
+ // its state, nothing is lost, and "Land now" stays available. `resolving` is populated only by a `merge` land:
736
+ // the paths written into the workspace carrying conflict markers, which the user finishes by hand.
737
737
  export const LandResultSchema = z.object({
738
- landed: z.boolean().describe("Whether anything was applied."),
739
- conflicts: z.array(LandConflictSchema).optional().describe("What stopped it, per repository."),
738
+ landed: z.boolean().describe("Whether the entire composed change was applied."),
739
+ conflicts: z.array(LandConflictSchema).optional().describe("What stopped the whole composed change, grouped per repository."),
740
740
  resolving: z
741
741
  .array(
742
742
  z.object({
@@ -745,7 +745,7 @@ export const LandResultSchema = z.object({
745
745
  }),
746
746
  )
747
747
  .optional()
748
- .describe("Files left half-merged, when you asked for the mode that lands what it can and leaves the rest marked up."),
748
+ .describe("Files left half-merged when you asked to carry the whole composition with its conflicts marked for resolution."),
749
749
  // A `measure` outcome with an outstanding delta: nothing was applied and nothing failed, the work is
750
750
  // waiting on the branch for a deliberate Land. `landed: false` alone can't say that (it means refusal).
751
751
  held: z
@@ -756,14 +756,13 @@ export const LandResultSchema = z.object({
756
756
  ),
757
757
  });
758
758
  export type LandResult = z.infer<typeof LandResultSchema>;
759
- /* land's input. `check` is the safe default and the historical behaviour: the delta is applied only if ALL of
760
- * it applies, so a refusal leaves the workspace byte-identical. `merge` is the escape hatch the conflict
761
- * report offers, a three-way apply that lands every clean path and leaves the rest with conflict markers to
762
- * resolve in place. It is opt-in because it WRITES on failure, which is the one thing `check` promises not
763
- * to do. `measure` is the auto-land-off mode: everything a land does EXCEPT touching the main tree, the
764
- * provenance commit onto agent/<id>, the cumulative diffstat, and the bookkeeping for work that reached the
765
- * main line by another road, so a held agent's card stays as current as a landed one's while its delta waits
766
- * on the branch for a deliberate Land. */
759
+ /* Land's input. `check` is the safe default: every repo is preflighted and the composition is applied only if
760
+ * ALL of it applies, so a refusal leaves every main tree byte-identical. `merge` is the escape hatch the
761
+ * conflict report offers, a three-way apply that carries the whole composition and leaves conflicted paths
762
+ * with markers to resolve in place. It is opt-in because it writes those markers. `measure` is the
763
+ * auto-land-off mode: everything a land does EXCEPT touching the main trees, the provenance commit onto
764
+ * agent/<id>, the cumulative diffstat, and the bookkeeping for work that reached main by another road, so a
765
+ * held agent's card stays current while its composed delta waits for a deliberate Land. */
767
766
  export const LandModeSchema = z.enum(["check", "merge", "measure"]);
768
767
  export type LandMode = z.infer<typeof LandModeSchema>;
769
768
  /* WHICH RUNG OF AN AGENT'S HISTORY A READING, or a land. STARTS AT.
@@ -795,7 +794,7 @@ export type AgentSpan = z.infer<typeof AgentSpanSchema>;
795
794
  export const AgentLandSchema = z.object({
796
795
  id: z.string().min(1).describe("Which conversation's work to merge."),
797
796
  mode: LandModeSchema.optional().describe(
798
- "How to apply it. The default applies all of it or none, so a refusal leaves the workspace exactly as it was. The other lands every clean file and leaves the rest with conflict markers to resolve by hand.",
797
+ "How to apply it. The default applies every repository or none, so a refusal leaves the workspace exactly as it was. The other carries the whole composition and leaves conflicted paths with markers to resolve by hand.",
799
798
  ),
800
799
  span: AgentSpanSchema.optional().describe("How much of the work to take. Leave it out for everything not yet merged."),
801
800
  force: z.boolean().optional().describe("Go ahead despite a check that would otherwise refuse."),
@@ -299,13 +299,15 @@ export const WorkspaceExtensionCreatedSchema = z.object({
299
299
  id: z.string().describe("The id it was given."),
300
300
  dir: z.string().describe("Where its files are, so you can open them."),
301
301
  });
302
- /* A batch of calls the host observed against this extension's declared routes, entryhow many since the last
303
- * report. Counts rather than events, and declared entries rather than concrete paths, because the question the
304
- * ledger answers is "is this permission earned?": a finer record would be a log of what the owner was doing,
305
- * indexed by extension, which is not a thing this product should be accumulating to answer it. */
306
- export const ExtensionUsageInputSchema = z.object({
307
- id: z.string().describe("Which extension."),
308
- used: z.record(z.string(), z.number().int().positive()).describe("Which of its declared powers it exercised, and how many times."),
302
+ /* Batches of calls the host observed against extensions' declared routes: extension id declared entry how
303
+ * many since the last report. Counts rather than events, and declared entries rather than concrete paths,
304
+ * because the question the ledger answers is "is this permission earned?": a finer record would be a log of
305
+ * what the owner was doing, indexed by extension, which is not a thing this product should be accumulating to
306
+ * answer it. Every extension rides one request so the bookkeeping cannot become its own request burst. */
307
+ export const ExtensionUsageBatchSchema = z.object({
308
+ reports: z
309
+ .record(z.string(), z.record(z.string(), z.number().int().positive()))
310
+ .describe("Each extension that called something, and the counts against the declared powers it exercised."),
309
311
  });
310
312
  // One declared background process (contributes.processes), status/start/stop, addressed by the capability
311
313
  // entry id + the manifest's process name. Undeclared names are NOT_FOUND, the manifest-honesty rule again.
@@ -101,16 +101,25 @@ export const WorkspaceTreeSchema = z.object({
101
101
  hidden: z.number().describe("How many entries at the top level were cut for size. Zero means the listing is complete."),
102
102
  });
103
103
  export type WorkspaceTree = z.infer<typeof WorkspaceTreeSchema>;
104
- // Lazy-load one directory's children, for a dir the tree walk listed but didn't descend into. Child dirs again
105
- // carry no `children`, so they lazy-load on their own expand. `hidden` = how many entries the cap cut (0 = all
106
- // listed).
104
+ // Lazy-load one directory's children, for a dir the tree walk listed but didn't descend into. The ordinary
105
+ // request is one level; a bounded `depth` lets a caller that genuinely needs a small subtree receive its
106
+ // descendants in the same flat `entries` list instead of issuing one request per directory.
107
107
  export const WorkspaceChildrenQuerySchema = WorkspaceScopeSchema.extend({
108
108
  path: z.string().min(1).describe("The folder to open, as a workspace path."),
109
+ depth: z.coerce
110
+ .number()
111
+ .int()
112
+ .min(1)
113
+ .max(5)
114
+ .optional()
115
+ .describe("How many levels to include. Omitted means direct children only; at most five levels can be read in one request."),
109
116
  });
110
117
  export const WorkspaceChildrenSchema = z.object({
111
118
  entries: z
112
119
  .array(WorkspaceTreeEntrySchema)
113
- .describe("What is directly inside it. Folders in here carry no contents of their own, so they open the same way."),
120
+ .describe(
121
+ "What is inside it, as a flat list. With the default depth these are direct children; a deeper request also includes descendants, whose full paths say where they belong. Folders carry no nested contents of their own.",
122
+ ),
114
123
  hidden: z.number().describe("How many entries were cut for size. Zero means the listing is complete."),
115
124
  });
116
125
  export type WorkspaceChildren = z.infer<typeof WorkspaceChildrenSchema>;
package/src/tunnel-ids.ts CHANGED
@@ -6,10 +6,10 @@ import { createHash } from "node:crypto";
6
6
  export const sha256Hex = (value: string): string => createHash("sha256").update(value).digest("hex");
7
7
 
8
8
  // The sandbox's stable 12-hex id, digested from the connect token. Used by:
9
- // • the CLI's sandbox-tunnel bootstrap (sandbox-tunnel.ts) to name the tunnel + DNS
10
- // • the preview hostname builder beside it (hostnames.ts)
11
- // • the sandbox daemon's sync SSH hostname derivation (sync.ts)
12
- // All three MUST agree on the digest, so it lives in the contract they share.
9
+ // • the hostname builders beside it (hostnames.ts) every public name embeds this id
10
+ // • the platform's reachability grant mint and tunnelId lookup (reachability.ts, ingress-contract.ts)
11
+ // • the desktop agent's loopback-port derivation for the direct-dial shortcut (daemon-base.ts)
12
+ // All of them MUST agree on the digest, so it lives in the contract they share.
13
13
  export const sandboxIdFromToken = (connectToken: string): string | undefined =>
14
14
  connectToken === "" ? undefined : sha256Hex(connectToken).slice(0, 12);
15
15