@dynamicagents/plugins 0.11.1 → 0.13.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 (134) hide show
  1. package/README.md +59 -79
  2. package/dist/browser/index.d.ts +0 -2
  3. package/dist/browser/index.js +21 -27
  4. package/dist/claude-code/cards.d.ts +53 -0
  5. package/dist/claude-code/cards.js +272 -0
  6. package/dist/claude-code/config.d.ts +73 -31
  7. package/dist/claude-code/config.js +0 -2
  8. package/dist/claude-code/credentials.d.ts +21 -9
  9. package/dist/claude-code/credentials.js +43 -9
  10. package/dist/claude-code/egress.d.ts +15 -14
  11. package/dist/claude-code/egress.js +51 -14
  12. package/dist/claude-code/events.d.ts +153 -9
  13. package/dist/claude-code/events.js +289 -58
  14. package/dist/claude-code/github.d.ts +39 -0
  15. package/dist/claude-code/github.js +82 -0
  16. package/dist/claude-code/index.d.ts +24 -80
  17. package/dist/claude-code/index.js +19 -234
  18. package/dist/claude-code/model.d.ts +152 -0
  19. package/dist/claude-code/model.js +342 -0
  20. package/dist/claude-code/run.d.ts +283 -92
  21. package/dist/claude-code/run.js +620 -114
  22. package/dist/claude-code/session.d.ts +131 -0
  23. package/dist/claude-code/session.js +285 -0
  24. package/dist/claude-code/spec.d.ts +46 -0
  25. package/dist/claude-code/spec.js +83 -0
  26. package/dist/claude-code/verified.d.ts +15 -0
  27. package/dist/claude-code/verified.js +15 -0
  28. package/dist/computer/context.d.ts +19 -0
  29. package/dist/computer/context.js +222 -0
  30. package/dist/computer/file-lock.d.ts +5 -0
  31. package/dist/computer/file-lock.js +40 -0
  32. package/dist/computer/gate.d.ts +12 -12
  33. package/dist/computer/gate.js +12 -12
  34. package/dist/computer/index.d.ts +57 -255
  35. package/dist/computer/index.js +98 -1039
  36. package/dist/computer/paths.d.ts +47 -22
  37. package/dist/computer/paths.js +64 -49
  38. package/dist/computer/proxy.d.ts +45 -0
  39. package/dist/computer/proxy.js +234 -0
  40. package/dist/computer/render.d.ts +27 -38
  41. package/dist/computer/render.js +32 -65
  42. package/dist/computer/tools-exec.d.ts +3 -0
  43. package/dist/computer/tools-exec.js +268 -0
  44. package/dist/computer/tools-file.d.ts +12 -0
  45. package/dist/computer/tools-file.js +64 -0
  46. package/dist/computer/tools-grep.d.ts +3 -0
  47. package/dist/computer/tools-grep.js +129 -0
  48. package/dist/repo/checkout.d.ts +35 -6
  49. package/dist/repo/checkout.js +64 -6
  50. package/dist/repo/context.d.ts +135 -0
  51. package/dist/repo/context.js +582 -0
  52. package/dist/repo/index.d.ts +79 -57
  53. package/dist/repo/index.js +118 -1112
  54. package/dist/repo/tools-checks.d.ts +3 -0
  55. package/dist/repo/tools-checks.js +112 -0
  56. package/dist/repo/tools-clone.d.ts +4 -0
  57. package/dist/repo/tools-clone.js +192 -0
  58. package/dist/repo/tools-pr.d.ts +14 -0
  59. package/dist/repo/tools-pr.js +196 -0
  60. package/dist/repo/tools-review.d.ts +12 -0
  61. package/dist/repo/tools-review.js +393 -0
  62. package/dist/repo/tools-worktree.d.ts +4 -0
  63. package/dist/repo/tools-worktree.js +305 -0
  64. package/dist/repo/tools-worktrees.d.ts +12 -0
  65. package/dist/repo/tools-worktrees.js +48 -0
  66. package/dist/repo/url.d.ts +2 -2
  67. package/dist/repo/url.js +7 -7
  68. package/dist/scratch/index.d.ts +4 -4
  69. package/dist/scratch/index.js +12 -11
  70. package/dist/{computer → workspace}/advisory.d.ts +33 -20
  71. package/dist/{computer → workspace}/advisory.js +32 -7
  72. package/dist/workspace/ca-trust.d.ts +95 -0
  73. package/dist/workspace/ca-trust.js +312 -0
  74. package/dist/workspace/container-deps.d.ts +54 -0
  75. package/dist/workspace/container-deps.js +224 -0
  76. package/dist/workspace/container-fault.d.ts +38 -0
  77. package/dist/workspace/container-fault.js +73 -0
  78. package/dist/workspace/exec.d.ts +94 -0
  79. package/dist/workspace/exec.js +153 -0
  80. package/dist/workspace/format.d.ts +36 -0
  81. package/dist/workspace/format.js +57 -0
  82. package/dist/workspace/git-host.d.ts +79 -0
  83. package/dist/workspace/git-host.js +226 -0
  84. package/dist/workspace/git-identity.d.ts +57 -0
  85. package/dist/workspace/git-identity.js +147 -0
  86. package/dist/workspace/index.d.ts +43 -47
  87. package/dist/workspace/index.js +52 -112
  88. package/dist/workspace/install-job.d.ts +121 -0
  89. package/dist/workspace/install-job.js +866 -0
  90. package/dist/{computer → workspace}/install.d.ts +15 -19
  91. package/dist/{computer → workspace}/install.js +8 -11
  92. package/dist/workspace/object.d.ts +502 -0
  93. package/dist/workspace/object.js +1427 -0
  94. package/dist/workspace/open.d.ts +95 -0
  95. package/dist/workspace/open.js +63 -0
  96. package/dist/workspace/read.d.ts +16 -0
  97. package/dist/workspace/read.js +22 -0
  98. package/dist/workspace/shell.d.ts +45 -0
  99. package/dist/workspace/shell.js +80 -0
  100. package/dist/workspace/sync.d.ts +111 -0
  101. package/dist/workspace/sync.js +124 -0
  102. package/dist/workspace/wake.d.ts +19 -0
  103. package/dist/workspace/wake.js +10 -0
  104. package/package.json +28 -42
  105. package/dist/arc-agi/analysis.d.ts +0 -336
  106. package/dist/arc-agi/analysis.js +0 -829
  107. package/dist/arc-agi/client.d.ts +0 -82
  108. package/dist/arc-agi/client.js +0 -113
  109. package/dist/arc-agi/game-tools.d.ts +0 -25
  110. package/dist/arc-agi/game-tools.js +0 -26
  111. package/dist/arc-agi/index.d.ts +0 -42
  112. package/dist/arc-agi/index.js +0 -175
  113. package/dist/arc-agi/main-agent.d.ts +0 -27
  114. package/dist/arc-agi/main-agent.js +0 -65
  115. package/dist/arc-agi/recipe.d.ts +0 -51
  116. package/dist/arc-agi/recipe.js +0 -100
  117. package/dist/arc-agi/scorecard.d.ts +0 -118
  118. package/dist/arc-agi/scorecard.js +0 -163
  119. package/dist/arc-agi/soul.d.ts +0 -40
  120. package/dist/arc-agi/soul.js +0 -90
  121. package/dist/arc-agi/store.d.ts +0 -154
  122. package/dist/arc-agi/store.js +0 -216
  123. package/dist/arc-agi/tools.d.ts +0 -36
  124. package/dist/arc-agi/tools.js +0 -576
  125. package/dist/arc-agi/types.d.ts +0 -212
  126. package/dist/arc-agi/types.js +0 -19
  127. package/dist/claude-code/recipe.d.ts +0 -53
  128. package/dist/claude-code/recipe.js +0 -100
  129. package/dist/computer/read.d.ts +0 -137
  130. package/dist/computer/read.js +0 -203
  131. package/dist/recall/index.d.ts +0 -99
  132. package/dist/recall/index.js +0 -171
  133. package/dist/triage/index.d.ts +0 -355
  134. package/dist/triage/index.js +0 -302
@@ -1,53 +1,49 @@
1
- import type { ToolSet } from "ai";
2
- import type { AgentPlugin, WorkspaceBacking, WorkspaceHandle } from "@dynamicagents/core";
3
1
  /**
4
- * `@dynamicagents/plugins/workspace` — a durable file store for long subagent runs,
5
- * and the model-facing tools over it.
6
- *
7
- * Core already owns the *interface*: `WorkspaceHandle`, `WorkspaceBacking`, the
8
- * per-file and file-count caps, and `makeWorkspaceHandle` which enforces them.
9
- * What core deliberately does not own is a **backend**, because the only good
10
- * one is `@cloudflare/shell` and shell is experimental ("expect breaking
11
- * changes"). An agent that never delegates file work should not carry that
12
- * dependency, so it ships here and is an optional peer.
13
- *
14
- * This is the only `@cloudflare/shell` import surface in the package — the same
15
- * discipline the predecessor kept, for the same reason: everything else codes
16
- * against core's stable wrapper rather than shell's large, churning API.
17
- *
18
- * Two halves, and they are independent:
19
- *
20
- * - `workspaceBacking` gives every subagent execution a real file store. An
21
- * agent that installs this plugin and nothing else still benefits, because the
22
- * tool families that persist session state to the workspace now have somewhere
23
- * durable to put it.
24
- * - the `workspace` tool family puts `ws_read`/`ws_write`/`ws_list` in front of
25
- * the *model*, so it can keep notes across a context window it will outlive.
26
- *
27
- * A recipe opts into the second by naming `workspace` in its `toolFamilies`;
28
- * the first applies to every execution regardless.
2
+ * `@dynamicagents/plugins/workspace` — the Durable Object a container workspace
3
+ * lives in, and the client side every other plugin reaches it through.
4
+ *
5
+ * The filesystem **is** a Durable Object's SQLite, mounted into the container
6
+ * over FUSE by `computerd`. Commands see a normal `/workspace`; the Worker reads
7
+ * the same tree over RPC; and when the container is replaced the tree is pushed
8
+ * back into the new one — so a checkout outlives the container that held it.
9
+ *
10
+ * `WorkspaceObjectBase` is the object: container backend, egress, CA trust,
11
+ * credentialed git, the dependency install, the sync drain and idle reclaim. A
12
+ * host subclasses it and answers a short config. Everything else here is what
13
+ * reaches it from outside: `openWorkspace`, `workspaceExec`, and the advisory
14
+ * vocabulary it reports its state in.
15
+ *
16
+ * `@dynamicagents/plugins/computer` is the agent's tools over it; `/repo` and
17
+ * `/scratch` take `workspaceExec` injected.
18
+ *
19
+ * Requires the Workers **Paid** plan (containers) and a Durable Object binding
20
+ * whose class extends `WorkspaceObjectBase` — see the README for the wrangler
21
+ * block.
29
22
  */
30
- /** This plugin's tool-family name, as a recipe's `toolFamilies` lists it. */
31
- export declare const WORKSPACE_FAMILY = "workspace";
23
+ /** How a repository installs its dependencies — the mechanical half. */
24
+ export { DEFAULT_INSTALL_PLAN, installFingerprint, resolveInstallCommand, type InstallPlan, type InstallProbe, type InstallResolution, type InstallRule, type InstallState } from "./install.js";
32
25
  /**
33
- * The model-facing workspace tools: read/write/list over the execution's durable
34
- * file store.
35
- *
36
- * Long recipes keep a small rolling context window, so these are how a model
37
- * persists anything it must remember after older turns scroll out. Exported
38
- * separately from the plugin so they unit-test without a runtime, and so a host
39
- * with its own tool assembly can reuse them.
26
+ * The workspace-advisory vocabulary, which a host needs all of: the type to
27
+ * return over RPC, `deriveAdvisories` to build it from what it already knows,
28
+ * and `sessionAdvisory` for a host driving a whole session rather than one
29
+ * command. `shapeOf` and `renderAdvisory` are exported for the specs that hold
30
+ * their exhaustiveness — a host has no reason to call either, since calling them
31
+ * would mean writing policy or wording that has one home already.
40
32
  */
41
- export declare function buildWorkspaceTools(workspace: WorkspaceHandle): ToolSet;
33
+ export { deriveAdvisories, renderAdvisory, sessionAdvisory, shapeOf, type AdvisoryAudience, type AdvisoryInput, type AdvisoryShape, type WorkspaceAdvisory } from "./advisory.js";
34
+ export { pathExists } from "./read.js";
35
+ export { cancelledNote, truncateOutput } from "./format.js";
36
+ export { openWorkspace, openWorkspaceFs, workspaceNameFromRuntime, WORKSPACE_RUNTIME_KEY, type WorkspaceHost } from "./open.js";
37
+ export { withShell, withShellTranscript } from "./shell.js";
38
+ export { workspaceExec, DEFAULT_CWD, DEFAULT_TIMEOUT_MS, type WorkspaceClientConfig } from "./exec.js";
42
39
  /**
43
- * Build a shell {@link Workspace} over a Durable Object's SQLite storage.
44
- *
45
- * The executing facet passes its *own* `ctx.storage.sql`, so per-execution
46
- * isolation is free and deleting the child wipes the workspace with the rest of
47
- * its storage. `name` is lazy because a facet's name is set after construction.
48
- *
49
- * Exported because a host that assembles its own `SubagentRuntime` by hand may
50
- * want it directly; the plugin's `workspaceBacking` is this same function.
40
+ * The object itself. The modules below import the client-side leaves beside
41
+ * them, never this barrel: a cycle through a module that builds a class at
42
+ * import time is a base that evaluates `undefined`.
51
43
  */
52
- export declare function durableWorkspaceBacking(sql: SqlStorage, name: () => string | undefined): WorkspaceBacking;
53
- export declare function workspace(): AgentPlugin;
44
+ export { WorkspaceObjectBase, IDLE_RECLAIM_MS, WORKSPACE_DIR, workspaceName, type WorkspaceObjectConfig, type WorkspaceGitConfig } from "./object.js";
45
+ export { InstallJob, type InstallJobDeps } from "./install-job.js";
46
+ export { WorkspaceSync, SYNC_DRAIN_BUDGET_MS, SYNC_DRAIN_RESUME_MS, SYNC_DRAIN_MAX_BACKOFF_MS, syncRetryDelayMs, type DrainOutcome, type SyncDrainIntent, type WorkspaceSyncDeps } from "./sync.js";
47
+ export { ContainerTrust, TRUST_CA_COMMAND, type ContainerTrustDeps } from "./ca-trust.js";
48
+ export { WorkspaceGitHost, type GitHostDeps } from "./git-host.js";
49
+ export type { WorkspaceWakeHandlers } from "./wake.js";
@@ -1,118 +1,58 @@
1
- import { tool } from "ai";
2
- import { z } from "zod";
3
- import { definePlugin } from "@dynamicagents/core";
4
- import { Workspace } from "@cloudflare/shell";
5
1
  /**
6
- * `@dynamicagents/plugins/workspace` — a durable file store for long subagent runs,
7
- * and the model-facing tools over it.
8
- *
9
- * Core already owns the *interface*: `WorkspaceHandle`, `WorkspaceBacking`, the
10
- * per-file and file-count caps, and `makeWorkspaceHandle` which enforces them.
11
- * What core deliberately does not own is a **backend**, because the only good
12
- * one is `@cloudflare/shell` and shell is experimental ("expect breaking
13
- * changes"). An agent that never delegates file work should not carry that
14
- * dependency, so it ships here and is an optional peer.
15
- *
16
- * This is the only `@cloudflare/shell` import surface in the package — the same
17
- * discipline the predecessor kept, for the same reason: everything else codes
18
- * against core's stable wrapper rather than shell's large, churning API.
19
- *
20
- * Two halves, and they are independent:
21
- *
22
- * - `workspaceBacking` gives every subagent execution a real file store. An
23
- * agent that installs this plugin and nothing else still benefits, because the
24
- * tool families that persist session state to the workspace now have somewhere
25
- * durable to put it.
26
- * - the `workspace` tool family puts `ws_read`/`ws_write`/`ws_list` in front of
27
- * the *model*, so it can keep notes across a context window it will outlive.
28
- *
29
- * A recipe opts into the second by naming `workspace` in its `toolFamilies`;
30
- * the first applies to every execution regardless.
2
+ * `@dynamicagents/plugins/workspace` — the Durable Object a container workspace
3
+ * lives in, and the client side every other plugin reaches it through.
4
+ *
5
+ * The filesystem **is** a Durable Object's SQLite, mounted into the container
6
+ * over FUSE by `computerd`. Commands see a normal `/workspace`; the Worker reads
7
+ * the same tree over RPC; and when the container is replaced the tree is pushed
8
+ * back into the new one — so a checkout outlives the container that held it.
9
+ *
10
+ * `WorkspaceObjectBase` is the object: container backend, egress, CA trust,
11
+ * credentialed git, the dependency install, the sync drain and idle reclaim. A
12
+ * host subclasses it and answers a short config. Everything else here is what
13
+ * reaches it from outside: `openWorkspace`, `workspaceExec`, and the advisory
14
+ * vocabulary it reports its state in.
15
+ *
16
+ * `@dynamicagents/plugins/computer` is the agent's tools over it; `/repo` and
17
+ * `/scratch` take `workspaceExec` injected.
18
+ *
19
+ * Requires the Workers **Paid** plan (containers) and a Durable Object binding
20
+ * whose class extends `WorkspaceObjectBase` — see the README for the wrangler
21
+ * block.
31
22
  */
32
- /** This plugin's tool-family name, as a recipe's `toolFamilies` lists it. */
33
- export const WORKSPACE_FAMILY = "workspace";
23
+ /** How a repository installs its dependencies — the mechanical half. */
24
+ export { DEFAULT_INSTALL_PLAN, installFingerprint, resolveInstallCommand } from "./install.js";
34
25
  /**
35
- * The model-facing workspace tools: read/write/list over the execution's durable
36
- * file store.
37
- *
38
- * Long recipes keep a small rolling context window, so these are how a model
39
- * persists anything it must remember after older turns scroll out. Exported
40
- * separately from the plugin so they unit-test without a runtime, and so a host
41
- * with its own tool assembly can reuse them.
26
+ * The workspace-advisory vocabulary, which a host needs all of: the type to
27
+ * return over RPC, `deriveAdvisories` to build it from what it already knows,
28
+ * and `sessionAdvisory` for a host driving a whole session rather than one
29
+ * command. `shapeOf` and `renderAdvisory` are exported for the specs that hold
30
+ * their exhaustiveness — a host has no reason to call either, since calling them
31
+ * would mean writing policy or wording that has one home already.
42
32
  */
43
- export function buildWorkspaceTools(workspace) {
44
- return {
45
- ws_read: tool({
46
- description: "Read a file from your workspace. Returns the file's text, or a note if it does not exist.",
47
- inputSchema: z.object({
48
- path: z.string().describe("File path, e.g. 'notes.md'")
49
- }),
50
- execute: async ({ path }) => {
51
- const content = await workspace.read(path);
52
- return content === null ? `(no file at ${path})` : content;
53
- }
54
- }),
55
- ws_write: tool({
56
- description: "Create or overwrite a workspace file. Use this to persist notes, hypotheses, and plans so you remember them after older turns scroll out of context.",
57
- inputSchema: z.object({
58
- path: z.string().describe("File path, e.g. 'notes.md'"),
59
- content: z
60
- .string()
61
- .describe("Full file content (overwrites any existing file)")
62
- }),
63
- execute: async ({ path, content }) => {
64
- // Returned rather than thrown: a write over the size cap is the model's
65
- // mistake to correct, and it can only correct what it is told. The SDK
66
- // would surface a throw as a tool error too, but this reads better and
67
- // keeps the limit itself in the message.
68
- try {
69
- await workspace.write(path, content);
70
- return `wrote ${path}`;
71
- }
72
- catch (err) {
73
- return `error writing ${path}: ${String(err)}`;
74
- }
75
- }
76
- }),
77
- ws_list: tool({
78
- description: "List the files currently in your workspace.",
79
- inputSchema: z.object({
80
- dir: z.string().optional().describe("Directory to list (default: root)")
81
- }),
82
- execute: async ({ dir }) => {
83
- const entries = await workspace.list(dir);
84
- if (entries.length === 0)
85
- return "(workspace is empty)";
86
- return entries
87
- .map((e) => `${e.path}${e.type === "directory" ? "/" : ""} (${e.size} bytes)`)
88
- .join("\n");
89
- }
90
- })
91
- };
92
- }
33
+ export { deriveAdvisories, renderAdvisory, sessionAdvisory, shapeOf } from "./advisory.js";
34
+ // A host implementing `InstallProbe` needs exactly this, and hand-rolling it
35
+ // loses the fast path: across a Durable Object boundary `fs` is a stub carrying
36
+ // `exists`, which a `stat`-only probe never asks for.
37
+ export { pathExists } from "./read.js";
38
+ export { cancelledNote, truncateOutput } from "./format.js";
39
+ export { openWorkspace, openWorkspaceFs, workspaceNameFromRuntime, WORKSPACE_RUNTIME_KEY } from "./open.js";
40
+ export { withShell, withShellTranscript } from "./shell.js";
41
+ export { workspaceExec, DEFAULT_CWD, DEFAULT_TIMEOUT_MS } from "./exec.js";
93
42
  /**
94
- * Build a shell {@link Workspace} over a Durable Object's SQLite storage.
95
- *
96
- * The executing facet passes its *own* `ctx.storage.sql`, so per-execution
97
- * isolation is free and deleting the child wipes the workspace with the rest of
98
- * its storage. `name` is lazy because a facet's name is set after construction.
99
- *
100
- * Exported because a host that assembles its own `SubagentRuntime` by hand may
101
- * want it directly; the plugin's `workspaceBacking` is this same function.
43
+ * The object itself. The modules below import the client-side leaves beside
44
+ * them, never this barrel: a cycle through a module that builds a class at
45
+ * import time is a base that evaluates `undefined`.
102
46
  */
103
- export function durableWorkspaceBacking(sql, name) {
104
- return new Workspace({ sql, name });
105
- }
106
- export function workspace() {
107
- return definePlugin({
108
- key: "workspace",
109
- workspaceBacking: durableWorkspaceBacking,
110
- toolFamilies: {
111
- [WORKSPACE_FAMILY]: (ctx) => ({
112
- tools: buildWorkspaceTools(ctx.workspace)
113
- })
114
- }
115
- // No `requires`: shell backs the workspace with the Durable Object's own
116
- // SQLite, which every DO already has. Nothing for the host to declare.
117
- });
118
- }
47
+ export { WorkspaceObjectBase, IDLE_RECLAIM_MS, WORKSPACE_DIR, workspaceName } from "./object.js";
48
+ // The dependency install, exported because a host that wants to report on one —
49
+ // or a spec that drives it — needs the type, not because anything but
50
+ // `./object.ts` constructs it.
51
+ export { InstallJob } from "./install-job.js";
52
+ // The pull the library owns no alarm for. Its constants are exported because a
53
+ // host deferring to a drain has to back off at the same rate this does.
54
+ export { WorkspaceSync, SYNC_DRAIN_BUDGET_MS, SYNC_DRAIN_RESUME_MS, SYNC_DRAIN_MAX_BACKOFF_MS, syncRetryDelayMs } from "./sync.js";
55
+ // `TRUST_CA_COMMAND` is exported so a host can assert what its image will be
56
+ // asked to run — see the file for why this cannot live in an entrypoint.
57
+ export { ContainerTrust, TRUST_CA_COMMAND } from "./ca-trust.js";
58
+ export { WorkspaceGitHost } from "./git-host.js";
@@ -0,0 +1,121 @@
1
+ import { type Workspace } from "@cloudflare/computer";
2
+ import type { Scheduler } from "@dynamicagents/core/alarm";
3
+ import { type InstallPlan, type InstallState } from "./install.js";
4
+ import type { WorkspaceWakeHandlers } from "./wake.js";
5
+ export interface InstallJobDeps {
6
+ storage: DurableObjectStorage;
7
+ scheduler: Scheduler<WorkspaceWakeHandlers>;
8
+ workspace: () => Workspace;
9
+ /** How this deployment installs dependencies for this agent's checkouts. */
10
+ plan: () => InstallPlan;
11
+ /** How long an install may run before it is killed. */
12
+ timeoutMs: () => number;
13
+ /** Set only when the workspace is over its ceiling. */
14
+ headroom: () => {
15
+ bytes: number;
16
+ capBytes: number;
17
+ } | undefined;
18
+ /** The object's own entry-point bookkeeping, which an install still owes. */
19
+ touch: () => Promise<void>;
20
+ ready: () => Promise<void>;
21
+ /** Hand a drain to the invocation, for the caller that can hold one. */
22
+ waitUntil: (promise: Promise<unknown>) => void;
23
+ /** A container was replaced, so nothing believed about it still holds. */
24
+ containerGone: () => Promise<void>;
25
+ tag: () => string;
26
+ id: () => string;
27
+ }
28
+ export declare class InstallJob {
29
+ #private;
30
+ private readonly deps;
31
+ constructor(deps: InstallJobDeps);
32
+ /**
33
+ * Start a dependency install the moment we can see one will be needed.
34
+ *
35
+ * The signal is {@link CONTAINER_TREE_KEY}: a local read, true only while the
36
+ * container that ran the install is the one running.
37
+ *
38
+ * Armed as soon as a container is up or a command is about to start one,
39
+ * because the model's first minute is README-reading and `git status` — an
40
+ * install armed there runs *through* that minute, where one armed on the first
41
+ * `npm` command charges its full time to that command.
42
+ *
43
+ * It writes `running` before anything is running: the alarm has not fired yet,
44
+ * and a `done` record would let an `npm` command through against a tree that
45
+ * is not there. That also makes this self-limiting — the next call sees
46
+ * `running` and stops.
47
+ */
48
+ armIfTreeMissing(): Promise<void>;
49
+ /** Where the last install ran, for the container setup's marker read. */
50
+ dir(): Promise<string | undefined>;
51
+ /** The container went away, and its tree with it. */
52
+ containerGone(): Promise<void>;
53
+ /**
54
+ * Check the record against the marker a new isolate's setup read.
55
+ *
56
+ * The record can outlive its container in an isolate that did not watch it
57
+ * exit; the marker cannot.
58
+ */
59
+ reconcile(marker: string | null): Promise<void>;
60
+ /**
61
+ * The record exactly as the job wrote it, with no staleness bound applied.
62
+ *
63
+ * {@link state} is what almost everything wants. This is for the one caller
64
+ * that must not repair anything on the way past: the container-idle handler,
65
+ * which only needs to know whether something is running before it destroys the
66
+ * container underneath it.
67
+ */
68
+ read(): Promise<InstallState>;
69
+ /**
70
+ * Start installing this checkout's dependencies, and return without waiting.
71
+ *
72
+ * Called from `repo_clone` through the repo plugin's `afterCheckout` hook, so
73
+ * it runs inside a model turn and must not block on the install — 225 seconds
74
+ * for slack-gatekeeper, against a turn that is cut at fifteen minutes.
75
+ *
76
+ * That caller is a model turn, which lives long enough to hold the drain handed
77
+ * to `ctx.waitUntil` below. **A short-lived caller cannot**, which is why an
78
+ * install the alarm drives is awaited inside that alarm rather than calling
79
+ * this.
80
+ */
81
+ start(req: {
82
+ dir: string;
83
+ repo?: string;
84
+ }): Promise<InstallState>;
85
+ /**
86
+ * Whether this container holds a finished tree, asked only when it qualifies a
87
+ * `deps-broken` advisory (see `deriveAdvisories`).
88
+ */
89
+ treePresentIfItMatters(install: InstallState): Promise<boolean>;
90
+ /**
91
+ * The install record itself, with its staleness bound and re-attach applied.
92
+ *
93
+ * Split from {@link advisories} so `startInstall` can consult the record
94
+ * without going through the `node_modules` probe, which needs a container and
95
+ * has nothing to say about whether an install may start.
96
+ *
97
+ * Re-attaches on the way past. An isolate reset leaves the record saying
98
+ * `running` with nothing draining it, and without this the state would say
99
+ * `running` forever while the command had long since finished.
100
+ */
101
+ state(): Promise<InstallState>;
102
+ /**
103
+ * When a reinstall was queued, if one is waiting to run.
104
+ *
105
+ * Read by {@link file://./advisory.ts deriveAdvisories}, which is the only
106
+ * caller that needs it: a `failed` record with a repair already queued is a
107
+ * transient condition wearing a permanent record's clothes.
108
+ */
109
+ reinstallArmedAt(): Promise<number | undefined>;
110
+ /**
111
+ * The armed reinstall came due.
112
+ *
113
+ * `clearArmed` first and unconditionally: this handler runs for minutes, and
114
+ * the stamp left in place is what a second arming would recognise as its own.
115
+ * The reservation in `#beginInstall` would catch a double, but the cheaper
116
+ * answer is not to schedule one.
117
+ */
118
+ onRun(): Promise<void>;
119
+ /** The watchdog: an install still running that nobody is draining. */
120
+ onWatch(): Promise<void>;
121
+ }