@fastagent-sh/fastagent 0.29.0 → 0.30.1
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.
- package/README.md +9 -4
- package/dist/atomic-write.d.ts +4 -5
- package/dist/atomic-write.js +4 -5
- package/dist/authoring.d.ts +32 -15
- package/dist/authoring.js +147 -127
- package/dist/channels/agentcore-protocol.d.ts +8 -3
- package/dist/channels/agentcore-protocol.js +3 -1
- package/dist/channels/agentcore-service.d.ts +1 -0
- package/dist/channels/agentcore-service.js +14 -4
- package/dist/channels/agentcore.d.ts +9 -0
- package/dist/channels/agentcore.js +29 -4
- package/dist/channels/context.d.ts +2 -0
- package/dist/channels/context.js +5 -1
- package/dist/channels/feishu/feishu-api.d.ts +2 -1
- package/dist/channels/feishu/feishu.d.ts +0 -3
- package/dist/channels/feishu/feishu.js +10 -10
- package/dist/channels/feishu/register-app.js +3 -5
- package/dist/channels/feishu/scaffold/channel.ts +32 -34
- package/dist/channels/feishu/scaffold/feishu-send.ts +5 -5
- package/dist/channels/feishu/scaffold/feishu-threads.ts +3 -3
- package/dist/channels/feishu/setup-mode.d.ts +2 -12
- package/dist/channels/feishu/setup-mode.js +2 -22
- package/dist/channels/feishu/setup.d.ts +12 -0
- package/dist/channels/feishu/setup.js +197 -0
- package/dist/channels/kit/abortable.d.ts +8 -0
- package/dist/channels/kit/abortable.js +22 -0
- package/dist/channels/lark/lark.d.ts +0 -3
- package/dist/channels/lark/lark.js +0 -5
- package/dist/channels/lark/scaffold/channel.ts +33 -35
- package/dist/channels/lark/scaffold/lark-send.ts +5 -5
- package/dist/channels/lark/scaffold/lark-threads.ts +3 -3
- package/dist/channels/lark/setup.d.ts +9 -0
- package/dist/channels/lark/setup.js +57 -0
- package/dist/channels/setup.d.ts +112 -0
- package/dist/channels/setup.js +31 -0
- package/dist/channels/slack/history.js +1 -1
- package/dist/channels/slack/manifest.d.ts +17 -7
- package/dist/channels/slack/manifest.js +12 -16
- package/dist/channels/slack/scaffold/channel.ts +44 -30
- package/dist/channels/slack/scaffold/slack-send.ts +8 -8
- package/dist/channels/slack/scaffold/slack-threads.ts +4 -4
- package/dist/channels/slack/setup.d.ts +7 -0
- package/dist/channels/slack/setup.js +119 -0
- package/dist/channels/slack/slack-api.d.ts +2 -0
- package/dist/channels/slack/slack-api.js +4 -0
- package/dist/channels/slack/slack.d.ts +21 -2
- package/dist/channels/slack/slack.js +398 -338
- package/dist/channels/slack/socket.d.ts +57 -0
- package/dist/channels/slack/socket.js +305 -0
- package/dist/channels/telegram/polling.d.ts +27 -0
- package/dist/channels/telegram/polling.js +105 -0
- package/dist/channels/telegram/scaffold/channel.ts +52 -32
- package/dist/channels/telegram/scaffold/telegram-send.ts +9 -9
- package/dist/channels/telegram/setup.d.ts +2 -0
- package/dist/channels/telegram/setup.js +42 -0
- package/dist/channels/telegram/telegram-api.d.ts +27 -1
- package/dist/channels/telegram/telegram-api.js +7 -6
- package/dist/channels/telegram/telegram.d.ts +11 -3
- package/dist/channels/telegram/telegram.js +184 -157
- package/dist/channels/webhook-evidence.d.ts +11 -0
- package/dist/channels/webhook-evidence.js +71 -0
- package/dist/channels/webhooks.d.ts +37 -0
- package/dist/channels/webhooks.js +70 -0
- package/dist/child-env.d.ts +16 -0
- package/dist/child-env.js +30 -0
- package/dist/cli/box-login.js +4 -1
- package/dist/cli/channel-app.d.ts +3 -0
- package/dist/cli/channel-app.js +35 -0
- package/dist/cli/channel-setup.d.ts +38 -0
- package/dist/cli/channel-setup.js +195 -0
- package/dist/cli/commands/add.d.ts +6 -14
- package/dist/cli/commands/add.js +45 -303
- package/dist/cli/commands/auth.js +8 -2
- package/dist/cli/commands/build.d.ts +5 -0
- package/dist/cli/commands/build.js +16 -0
- package/dist/cli/commands/channels.d.ts +19 -0
- package/dist/cli/commands/channels.js +230 -0
- package/dist/cli/commands/content.d.ts +7 -3
- package/dist/cli/commands/content.js +16 -10
- package/dist/cli/commands/deploy/agentcore.js +55 -23
- package/dist/cli/commands/deploy/channel-apps.d.ts +17 -0
- package/dist/cli/commands/deploy/channel-apps.js +30 -0
- package/dist/cli/commands/deploy/docker.js +32 -65
- package/dist/cli/commands/deploy/fly.js +28 -12
- package/dist/cli/commands/deploy/railway.js +38 -13
- package/dist/cli/commands/deploy/secrets-step.d.ts +19 -0
- package/dist/cli/commands/deploy/secrets-step.js +66 -0
- package/dist/cli/commands/deploy/shared.d.ts +16 -5
- package/dist/cli/commands/deploy/shared.js +25 -8
- package/dist/cli/commands/deploy.js +53 -60
- package/dist/cli/commands/dev.d.ts +2 -0
- package/dist/cli/commands/dev.js +15 -3
- package/dist/cli/commands/env.js +1 -1
- package/dist/cli/commands/info.d.ts +2 -0
- package/dist/cli/commands/info.js +60 -25
- package/dist/cli/commands/init.js +3 -1
- package/dist/cli/commands/invoke.d.ts +2 -0
- package/dist/cli/commands/invoke.js +20 -7
- package/dist/cli/commands/login.d.ts +0 -7
- package/dist/cli/commands/login.js +22 -10
- package/dist/cli/commands/logout.js +1 -1
- package/dist/cli/commands/mcp.js +14 -6
- package/dist/cli/commands/models.js +3 -2
- package/dist/cli/commands/schedules.d.ts +4 -2
- package/dist/cli/commands/schedules.js +14 -10
- package/dist/cli/commands/secrets.d.ts +14 -0
- package/dist/cli/commands/secrets.js +213 -0
- package/dist/cli/commands/start.d.ts +14 -14
- package/dist/cli/commands/start.js +46 -60
- package/dist/cli/content-view.d.ts +4 -6
- package/dist/cli/content-view.js +5 -11
- package/dist/cli/first-run-channels.d.ts +3 -0
- package/dist/cli/first-run-channels.js +63 -0
- package/dist/cli/instance.d.ts +41 -0
- package/dist/cli/instance.js +155 -0
- package/dist/cli/invoke-stream.d.ts +5 -2
- package/dist/cli/invoke-stream.js +7 -2
- package/dist/cli/kernel.js +3 -0
- package/dist/cli/program.js +282 -110
- package/dist/cli/serve.d.ts +4 -5
- package/dist/cli/serve.js +4 -7
- package/dist/cli/shared.d.ts +11 -2
- package/dist/cli/shared.js +32 -19
- package/dist/cli/ticket.d.ts +7 -0
- package/dist/cli/ticket.js +106 -30
- package/dist/content/declare.d.ts +31 -37
- package/dist/content/declare.js +59 -60
- package/dist/content/file.d.ts +23 -12
- package/dist/content/file.js +48 -35
- package/dist/content/git.d.ts +0 -10
- package/dist/content/git.js +5 -39
- package/dist/content/resolve.d.ts +18 -22
- package/dist/content/resolve.js +32 -66
- package/dist/content/source.d.ts +7 -8
- package/dist/content/source.js +10 -28
- package/dist/credentials-page.d.ts +26 -0
- package/dist/credentials-page.js +185 -0
- package/dist/declared-secrets.d.ts +10 -3
- package/dist/declared-secrets.js +8 -4
- package/dist/deploy/agentcore/destroy.d.ts +4 -1
- package/dist/deploy/agentcore/destroy.js +25 -1
- package/dist/deploy/agentcore/forwarder.js +1 -1
- package/dist/deploy/agentcore/plan.d.ts +7 -21
- package/dist/deploy/agentcore/plan.js +47 -49
- package/dist/deploy/agentcore/run.d.ts +18 -10
- package/dist/deploy/agentcore/run.js +93 -70
- package/dist/deploy/agentcore/runtime-secrets.d.ts +7 -0
- package/dist/deploy/agentcore/runtime-secrets.js +108 -0
- package/dist/deploy/agentcore/shell.js +12 -19
- package/dist/deploy/agentcore/sigv4.d.ts +7 -0
- package/dist/deploy/agentcore/sigv4.js +15 -0
- package/dist/deploy/agentcore/slr.d.ts +18 -0
- package/dist/deploy/agentcore/slr.js +27 -0
- package/dist/deploy/agentcore/store.d.ts +7 -0
- package/dist/deploy/agentcore/store.js +115 -0
- package/dist/deploy/api.d.ts +14 -14
- package/dist/deploy/api.js +26 -24
- package/dist/deploy/box-shell.d.ts +3 -1
- package/dist/deploy/build-context.d.ts +4 -4
- package/dist/deploy/build-context.js +11 -15
- package/dist/deploy/channel-ingress.d.ts +35 -9
- package/dist/deploy/channel-ingress.js +119 -22
- package/dist/deploy/container.d.ts +35 -10
- package/dist/deploy/container.js +79 -37
- package/dist/deploy/delivered-text.d.ts +13 -0
- package/dist/deploy/delivered-text.js +86 -0
- package/dist/deploy/docker/plan.d.ts +7 -8
- package/dist/deploy/docker/plan.js +31 -52
- package/dist/deploy/docker/run.d.ts +5 -43
- package/dist/deploy/docker/run.js +9 -84
- package/dist/deploy/file-store.d.ts +2 -0
- package/dist/deploy/file-store.js +17 -0
- package/dist/deploy/fly/plan.d.ts +3 -2
- package/dist/deploy/fly/plan.js +20 -9
- package/dist/deploy/fly/run.d.ts +18 -8
- package/dist/deploy/fly/run.js +24 -42
- package/dist/deploy/fly/store.d.ts +12 -0
- package/dist/deploy/fly/store.js +83 -0
- package/dist/deploy/hosts.d.ts +1 -2
- package/dist/deploy/hosts.js +1 -2
- package/dist/deploy/preflight.d.ts +18 -5
- package/dist/deploy/preflight.js +135 -63
- package/dist/deploy/railway/ignore.d.ts +8 -0
- package/dist/deploy/railway/ignore.js +57 -0
- package/dist/deploy/railway/plan.d.ts +1 -2
- package/dist/deploy/railway/plan.js +8 -6
- package/dist/deploy/railway/run.d.ts +21 -15
- package/dist/deploy/railway/run.js +32 -78
- package/dist/deploy/railway/store.d.ts +29 -0
- package/dist/deploy/railway/store.js +143 -0
- package/dist/deploy/runner.d.ts +5 -2
- package/dist/deploy/runner.js +4 -3
- package/dist/deploy/secret-store.d.ts +63 -0
- package/dist/deploy/secret-store.js +98 -0
- package/dist/deploy/secrets.d.ts +29 -46
- package/dist/deploy/secrets.js +49 -122
- package/dist/deploy/workspace.d.ts +6 -12
- package/dist/deploy/workspace.js +18 -94
- package/dist/dev-supervisor.js +6 -8
- package/dist/environment/declare.js +3 -2
- package/dist/environment/mise.d.ts +3 -1
- package/dist/environment/mise.js +4 -2
- package/dist/feishu.d.ts +1 -1
- package/dist/feishu.js +1 -1
- package/dist/harnesses/models/catalog.d.ts +1 -0
- package/dist/harnesses/models/catalog.js +1 -2
- package/dist/harnesses/models/environment.d.ts +7 -2
- package/dist/harnesses/models/environment.js +9 -5
- package/dist/harnesses/models/host.d.ts +0 -7
- package/dist/harnesses/models/host.js +10 -1
- package/dist/harnesses/models/login.d.ts +0 -8
- package/dist/harnesses/models/login.js +5 -4
- package/dist/harnesses/models/models.d.ts +7 -2
- package/dist/harnesses/models/models.js +28 -4
- package/dist/harnesses/pi-durable/agent.js +59 -38
- package/dist/harnesses/pi-durable/build.d.ts +12 -0
- package/dist/harnesses/pi-durable/build.js +270 -0
- package/dist/harnesses/pi-durable/built.d.ts +24 -0
- package/dist/harnesses/pi-durable/built.js +136 -0
- package/dist/harnesses/pi-durable/config.d.ts +81 -0
- package/dist/harnesses/pi-durable/config.js +266 -0
- package/dist/harnesses/pi-durable/define.d.ts +63 -13
- package/dist/harnesses/pi-durable/define.js +23 -2
- package/dist/harnesses/pi-durable/definition.d.ts +72 -0
- package/dist/harnesses/pi-durable/definition.js +143 -0
- package/dist/harnesses/pi-durable/events.d.ts +4 -3
- package/dist/harnesses/pi-durable/events.js +179 -136
- package/dist/harnesses/pi-durable/execution-env.d.ts +17 -0
- package/dist/harnesses/pi-durable/execution-env.js +11 -0
- package/dist/harnesses/pi-durable/mcp.js +1 -3
- package/dist/harnesses/pi-durable/open.d.ts +35 -37
- package/dist/harnesses/pi-durable/open.js +91 -153
- package/dist/harnesses/pi-durable/reads.d.ts +0 -1
- package/dist/harnesses/pi-durable/reads.js +1 -3
- package/dist/harnesses/pi-durable/registry.d.ts +4 -6
- package/dist/harnesses/pi-durable/registry.js +29 -26
- package/dist/harnesses/pi-durable/release.d.ts +2 -2
- package/dist/harnesses/pi-durable/release.js +10 -7
- package/dist/harnesses/pi-durable/serve.d.ts +91 -15
- package/dist/harnesses/pi-durable/serve.js +109 -47
- package/dist/harnesses/pi-durable/sessions.js +15 -12
- package/dist/harnesses/pi-durable/text-sources.d.ts +30 -0
- package/dist/harnesses/pi-durable/text-sources.js +55 -0
- package/dist/harnesses/pi-durable/text.d.ts +16 -4
- package/dist/harnesses/pi-durable/text.js +115 -59
- package/dist/harnesses/pi-durable/wake.js +8 -8
- package/dist/http/client.js +9 -3
- package/dist/http/contract.d.ts +3 -3
- package/dist/http/server.d.ts +1 -1
- package/dist/http/server.js +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.js +4 -1
- package/dist/instance-name.d.ts +7 -0
- package/dist/instance-name.js +26 -0
- package/dist/lark.d.ts +1 -1
- package/dist/lark.js +1 -1
- package/dist/mcp/client.js +11 -2
- package/dist/mcp/config.d.ts +70 -18
- package/dist/mcp/config.js +136 -53
- package/dist/mcp/host.d.ts +5 -2
- package/dist/mcp/host.js +14 -6
- package/dist/mcp/sign-in.js +2 -2
- package/dist/mcp-api.d.ts +14 -0
- package/dist/paths.d.ts +22 -8
- package/dist/paths.js +44 -11
- package/dist/runtime-websocket.d.ts +14 -0
- package/dist/runtime-websocket.js +39 -0
- package/dist/scaffold/add-channel.d.ts +9 -16
- package/dist/scaffold/add-channel.js +13 -83
- package/dist/scaffold/templates/env.example +4 -5
- package/dist/scaffold/templates/fastagent.config.ts +20 -14
- package/dist/scaffold/templates/gitignore +9 -6
- package/dist/scaffold/templates.d.ts +6 -2
- package/dist/scaffold/templates.js +7 -2
- package/dist/scaffold/vendor-skill.js +4 -2
- package/dist/service.d.ts +44 -6
- package/dist/service.js +110 -10
- package/dist/serving-command.d.ts +10 -0
- package/dist/serving-command.js +1 -0
- package/dist/slack.d.ts +1 -1
- package/dist/slack.js +1 -1
- package/dist/strip-edges.d.ts +10 -0
- package/dist/strip-edges.js +22 -0
- package/dist/telegram.d.ts +1 -1
- package/dist/telegram.js +1 -1
- package/dist/tunnel.d.ts +0 -1
- package/dist/tunnel.js +2 -8
- package/dist/value-file.d.ts +11 -6
- package/dist/value-file.js +21 -9
- package/dist/version.d.ts +7 -1
- package/dist/version.js +9 -3
- package/package.json +6 -5
- package/dist/channels/lark/credentials-page.d.ts +0 -25
- package/dist/channels/lark/credentials-page.js +0 -206
- package/dist/channels/lark/onboard.d.ts +0 -52
- package/dist/channels/lark/onboard.js +0 -86
- package/dist/channels/slack/config-api.d.ts +0 -69
- package/dist/channels/slack/config-api.js +0 -162
- package/dist/channels/slack/onboard.d.ts +0 -40
- package/dist/channels/slack/onboard.js +0 -136
- package/dist/channels/slack/onboarding-state.d.ts +0 -31
- package/dist/channels/slack/onboarding-state.js +0 -64
- package/dist/channels/slack/register-webhook.d.ts +0 -12
- package/dist/channels/slack/register-webhook.js +0 -67
- package/dist/channels/slack/setup-server.d.ts +0 -32
- package/dist/channels/slack/setup-server.js +0 -246
- package/dist/cli/add-feishu.d.ts +0 -41
- package/dist/cli/add-feishu.js +0 -391
- package/dist/cli/add-slack.d.ts +0 -18
- package/dist/cli/add-slack.js +0 -216
- package/dist/harnesses/pi-durable/parked.d.ts +0 -18
- package/dist/harnesses/pi-durable/parked.js +0 -27
package/dist/content/declare.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* WHAT AN
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* is
|
|
2
|
+
* WHAT AN AGENT WORKS ON, declared and refused in ONE place (file.ts reads the files through it): the `content` map of
|
|
3
|
+
* the program's `context.json`, which holds only repositories every instance reaches, and the `content` map of an
|
|
4
|
+
* instance's `fastagent.json`, which adds repositories and directories of its own. An instance only adds: a name the
|
|
5
|
+
* program declares is not one it may take. Pure: what is on the disk is resolve.ts's question.
|
|
6
|
+
* docs/design/agent-artifact.md §3.3 and §4.2 are the rule.
|
|
6
7
|
*/
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { CONTEXT_FILE, LOCAL_CONTEXT_FILE, isUnderDir } from "../paths.js";
|
|
8
|
+
import { isAbsolute } from "node:path";
|
|
9
|
+
import { CONTEXT_FILE, configurationPath, isUnderDir } from "../paths.js";
|
|
10
10
|
/**
|
|
11
|
-
* The keys an entry
|
|
12
|
-
*
|
|
11
|
+
* The keys an entry carries, in the order they are written: where it is, then how it is treated. One list each, so a
|
|
12
|
+
* key the reader accepts is one the writer keeps.
|
|
13
13
|
*/
|
|
14
|
-
const
|
|
15
|
-
const
|
|
14
|
+
const GITHUB_KEYS = ["github", "ref", "description"];
|
|
15
|
+
const PATH_KEYS = ["path", "description"];
|
|
16
16
|
/** A name becomes a directory name, so it is one path segment (the spelling a release's agent name has). */
|
|
17
17
|
const NAME = /^[A-Za-z0-9_-]+$/;
|
|
18
18
|
/** Whether `name` can name a content entry. */
|
|
@@ -24,13 +24,9 @@ const GITHUB_REPO = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
|
|
|
24
24
|
export function isGithubRepo(repo) {
|
|
25
25
|
return GITHUB_REPO.test(repo);
|
|
26
26
|
}
|
|
27
|
-
/** `entry` with its keys in
|
|
27
|
+
/** `entry` with its keys in the order they are written. */
|
|
28
28
|
export function canonicalEntry(entry) {
|
|
29
|
-
return pick(entry,
|
|
30
|
-
}
|
|
31
|
-
/** `binding` with its keys in {@link BINDING_KEYS} order: the form written. */
|
|
32
|
-
export function canonicalBinding(binding) {
|
|
33
|
-
return pick(binding, BINDING_KEYS);
|
|
29
|
+
return pick(entry, "github" in entry ? GITHUB_KEYS : PATH_KEYS);
|
|
34
30
|
}
|
|
35
31
|
function pick(value, keys) {
|
|
36
32
|
const out = {};
|
|
@@ -41,42 +37,26 @@ function pick(value, keys) {
|
|
|
41
37
|
}
|
|
42
38
|
return out;
|
|
43
39
|
}
|
|
44
|
-
/**
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Read a `content` map (undefined is none) from `from`. Every refusal names the entry; nothing is defaulted. The
|
|
42
|
+
* program's declares repositories only, since it is shared; an instance's may name a directory too.
|
|
43
|
+
*/
|
|
44
|
+
export function declareContent(raw, from) {
|
|
45
|
+
return entriesByName(raw).map(([name, entry]) => declareOne(name, entry, from));
|
|
47
46
|
}
|
|
48
47
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* machine alone.
|
|
48
|
+
* The program's entries and the instance's, as one list. An instance only adds: a name both declare (ignoring case,
|
|
49
|
+
* as names are a directory) is refused, naming both, so nothing is shadowed.
|
|
52
50
|
*/
|
|
53
|
-
export function
|
|
54
|
-
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const path = absolutePath(e.path, agentDir);
|
|
60
|
-
const shared = declared.find((entry) => entry.name.toLowerCase() === name.toLowerCase());
|
|
61
|
-
if (shared !== undefined) {
|
|
62
|
-
if (shared.name !== name) {
|
|
63
|
-
throw new Error(`${at} binds the entry ${CONTEXT_FILE} names "${shared.name}": spell it the same`);
|
|
64
|
-
}
|
|
65
|
-
if (e.description !== undefined) {
|
|
66
|
-
throw new Error(`${at} binds this machine's checkout of the entry ${CONTEXT_FILE} declares, which says "description" for ` +
|
|
67
|
-
`every instance: give it only "path"`);
|
|
68
|
-
}
|
|
69
|
-
return { name, path, kind: "checkout" };
|
|
51
|
+
export function joinContent(program, instance) {
|
|
52
|
+
for (const added of instance) {
|
|
53
|
+
const taken = program.find((entry) => entry.name.toLowerCase() === added.name.toLowerCase());
|
|
54
|
+
if (taken !== undefined) {
|
|
55
|
+
throw new Error(`content "${added.name}" is declared by the program (${CONTEXT_FILE} names "${taken.name}") and by the ` +
|
|
56
|
+
`instance: an instance adds to the program's content and does not replace it — name it otherwise`);
|
|
70
57
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
/** `path` as written in `context.local.json`, absolute: `~/` is the home directory, a relative one the agent's. */
|
|
76
|
-
function absolutePath(path, agentDir) {
|
|
77
|
-
if (path === "~" || path.startsWith("~/"))
|
|
78
|
-
return join(homedir(), path.slice(1));
|
|
79
|
-
return isAbsolute(path) ? resolve(path) : resolve(agentDir, path);
|
|
58
|
+
}
|
|
59
|
+
return [...program, ...instance];
|
|
80
60
|
}
|
|
81
61
|
/** The entries of a `content` map, each name checked, unique ignoring case. */
|
|
82
62
|
function entriesByName(raw) {
|
|
@@ -110,24 +90,43 @@ function objectWithKeys(at, value, keys) {
|
|
|
110
90
|
}
|
|
111
91
|
return e;
|
|
112
92
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
93
|
+
/** `path` as written in an instance configuration, absolute: `~/` is the home directory, a relative one `base`'s. */
|
|
94
|
+
function absolutePath(path, from, at) {
|
|
95
|
+
const absolute = configurationPath(path, from.base);
|
|
96
|
+
if (absolute === undefined) {
|
|
97
|
+
throw new Error(`${at}: "path" must be absolute here, since ${from.file} is not a file its directory could anchor`);
|
|
116
98
|
}
|
|
117
|
-
return
|
|
99
|
+
return absolute;
|
|
118
100
|
}
|
|
119
|
-
function declareOne(name, entry) {
|
|
101
|
+
function declareOne(name, entry, from) {
|
|
120
102
|
const at = `content "${name}"`;
|
|
121
|
-
const e = objectWithKeys(at, entry,
|
|
122
|
-
|
|
103
|
+
const e = objectWithKeys(at, entry, [...GITHUB_KEYS, "path"]);
|
|
104
|
+
if (from.origin === "program" && e.path !== undefined) {
|
|
105
|
+
throw new Error(`${at}: ${from.file} is shared, so it declares only the repositories every instance reaches — add a directory ` +
|
|
106
|
+
`to the instance's configuration instead (fastagent content add <dir>)`);
|
|
107
|
+
}
|
|
108
|
+
for (const key of ["github", "ref", "path"]) {
|
|
123
109
|
if (e[key] !== undefined && (typeof e[key] !== "string" || e[key] === "")) {
|
|
124
110
|
throw new Error(`${at}: "${key}" must be a non-empty string`);
|
|
125
111
|
}
|
|
126
112
|
}
|
|
127
|
-
|
|
113
|
+
if (e.description !== undefined && (typeof e.description !== "string" || e.description === "")) {
|
|
114
|
+
throw new Error(`${at}: "description" must be a non-empty string`);
|
|
115
|
+
}
|
|
116
|
+
const base = {
|
|
117
|
+
name,
|
|
118
|
+
origin: from.origin,
|
|
119
|
+
...(e.description !== undefined ? { description: e.description } : {}),
|
|
120
|
+
};
|
|
121
|
+
if (e.github !== undefined && e.path !== undefined)
|
|
122
|
+
throw new Error(`${at} names both "github" and "path": give one`);
|
|
123
|
+
if (e.path !== undefined) {
|
|
124
|
+
if (e.ref !== undefined)
|
|
125
|
+
throw new Error(`${at}: "ref" applies to a repository, and ${at} is a directory`);
|
|
126
|
+
return { ...base, kind: "local", path: absolutePath(e.path, from, at) };
|
|
127
|
+
}
|
|
128
128
|
if (e.github === undefined) {
|
|
129
|
-
throw new Error(`${at} needs "github"
|
|
130
|
-
`directory of this machine in ${LOCAL_CONTEXT_FILE} instead (fastagent content add <dir>)`);
|
|
129
|
+
throw new Error(`${at} needs "github"${from.origin === "instance" ? ' or "path"' : ""}`);
|
|
131
130
|
}
|
|
132
131
|
const repo = e.github;
|
|
133
132
|
if (!isGithubRepo(repo))
|
|
@@ -136,7 +135,7 @@ function declareOne(name, entry) {
|
|
|
136
135
|
// git reads a leading "-" as an option, and no branch, tag or commit name has one.
|
|
137
136
|
if (ref?.startsWith("-"))
|
|
138
137
|
throw new Error(`${at}: "ref" must name a branch, tag or commit, got "${ref}"`);
|
|
139
|
-
return {
|
|
138
|
+
return { ...base, kind: "github", repo, ...(ref !== undefined ? { ref } : {}) };
|
|
140
139
|
}
|
|
141
140
|
/**
|
|
142
141
|
* A directory the agent is bound to and the agent directory are kept apart (agent-model.md §2): a definition is
|
package/dist/content/file.d.ts
CHANGED
|
@@ -1,32 +1,43 @@
|
|
|
1
1
|
import { type DeclaredEnvironment } from "../environment/declare.ts";
|
|
2
|
-
import { type
|
|
2
|
+
import { type ContentEntry, type DeclaredContent } from "./declare.ts";
|
|
3
3
|
/** `context.json` as read: the content entries as written and as declared, and the environment. */
|
|
4
4
|
export interface ContextFile {
|
|
5
5
|
$schema?: string;
|
|
6
6
|
content: Record<string, ContentEntry>;
|
|
7
7
|
declared: DeclaredContent[];
|
|
8
8
|
environment?: DeclaredEnvironment;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export interface LocalContextFile {
|
|
12
|
-
content: Record<string, ContentBinding>;
|
|
13
|
-
bound: BoundContent[];
|
|
9
|
+
/** The program's MCP servers as written. Their shape is the MCP reader's to check; an edit keeps them as they are. */
|
|
10
|
+
mcpServers?: Record<string, unknown>;
|
|
14
11
|
}
|
|
15
12
|
/** Read `text`, the contents of `path`, whole: what an edit, which writes the whole, reads. */
|
|
16
13
|
export declare function parseContextFile(text: string, path: string): ContextFile;
|
|
17
|
-
/** Read `text`, the contents of `path`, whole, beside the entries `context.json` declares. */
|
|
18
|
-
export declare function parseLocalContextFile(text: string, path: string, declared: readonly DeclaredContent[], agentDir: string): LocalContextFile;
|
|
19
14
|
/** The agent's `context.json`, read whole. */
|
|
20
15
|
export declare function readContextFile(agentDir: string): ContextFile;
|
|
21
|
-
/** The content
|
|
22
|
-
export
|
|
16
|
+
/** The instance configuration's content, as far as this reads it: its `content` map and where it is from. */
|
|
17
|
+
export interface InstanceContent {
|
|
18
|
+
values: unknown;
|
|
19
|
+
label: string;
|
|
20
|
+
/** The configuration file's directory, which a relative `path` is relative to. */
|
|
21
|
+
directory?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The content of the agent whose program is in `agentDir`: what its `context.json` declares, and what `instance` adds
|
|
25
|
+
* to it (an instance only adds: a name both declare is refused).
|
|
26
|
+
*/
|
|
27
|
+
export declare function loadContent(agentDir: string, instance?: InstanceContent): DeclaredContent[];
|
|
28
|
+
/** What an instance configuration's `content` declares. */
|
|
29
|
+
export declare function instanceContent({ values, label, directory }: InstanceContent): DeclaredContent[];
|
|
23
30
|
/** The environment the agent in `agentDir` declares, or undefined when it declares none. */
|
|
24
31
|
export declare function loadEnvironment(agentDir: string): DeclaredEnvironment | undefined;
|
|
32
|
+
/** The program's `mcpServers` map as written in `context.json`, and the file's path, which names it in a refusal. */
|
|
33
|
+
export declare function readProgramMcpServers(agentDir: string): {
|
|
34
|
+
values: unknown;
|
|
35
|
+
path: string;
|
|
36
|
+
};
|
|
25
37
|
/** The text `context.json` is written as. An environment that declares nothing is left out. */
|
|
26
38
|
export declare function contextFileText(file: {
|
|
27
39
|
$schema?: string;
|
|
28
40
|
content: Record<string, ContentEntry>;
|
|
29
41
|
environment?: DeclaredEnvironment;
|
|
42
|
+
mcpServers?: Record<string, unknown>;
|
|
30
43
|
}): string;
|
|
31
|
-
/** The text `context.local.json` is written as. */
|
|
32
|
-
export declare function localContextFileText(content: Record<string, ContentBinding>): string;
|
package/dist/content/file.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
3
|
-
* `content list`, `env`, `tool` and deploy read one declaration; and the one shape
|
|
4
|
-
* declares the part it uses (its content, or its environment), so a part that is refused stops what uses
|
|
5
|
-
* reported where it is, not as the other's; an edit declares the whole, since it writes the whole. JSON,
|
|
6
|
-
* `mcp.json` and `package.json`, so a command, a client or the agent itself can edit it without touching
|
|
2
|
+
* The program's `context.json` and the content an instance's configuration adds, read in ONE place, so the opener,
|
|
3
|
+
* `info`, `content list`, `env`, `tool` and deploy read one declaration; and the one shape `context.json` is written
|
|
4
|
+
* in. A reader declares the part it uses (its content, or its environment), so a part that is refused stops what uses
|
|
5
|
+
* it and is reported where it is, not as the other's; an edit declares the whole, since it writes the whole. JSON,
|
|
6
|
+
* like `mcp.json` and `package.json`, so a command, a client or the agent itself can edit it without touching
|
|
7
|
+
* TypeScript.
|
|
7
8
|
*/
|
|
8
9
|
import { readFileSync } from "node:fs";
|
|
9
10
|
import { join, resolve } from "node:path";
|
|
10
|
-
import { CONTEXT_FILE
|
|
11
|
+
import { CONTEXT_FILE } from "../paths.js";
|
|
11
12
|
import { declareEnvironment } from "../environment/declare.js";
|
|
12
|
-
import {
|
|
13
|
-
const FILE_KEYS = ["$schema", "content", "environment"];
|
|
14
|
-
const LOCAL_FILE_KEYS = ["content"];
|
|
13
|
+
import { declareContent, joinContent } from "./declare.js";
|
|
14
|
+
const FILE_KEYS = ["$schema", "content", "environment", "mcpServers"];
|
|
15
15
|
/** `text`, the contents of `path`, as the object a context file is: refused when the file itself is wrong. */
|
|
16
|
-
function parseFile(text, path
|
|
16
|
+
function parseFile(text, path) {
|
|
17
17
|
let raw;
|
|
18
18
|
try {
|
|
19
19
|
raw = JSON.parse(text);
|
|
@@ -25,12 +25,17 @@ function parseFile(text, path, keys = FILE_KEYS) {
|
|
|
25
25
|
throw new Error(`${path} must hold a JSON object`);
|
|
26
26
|
const file = raw;
|
|
27
27
|
for (const key of Object.keys(file)) {
|
|
28
|
-
if (!
|
|
29
|
-
throw new Error(`${path}: unknown key "${key}" (valid keys: ${
|
|
28
|
+
if (!FILE_KEYS.includes(key)) {
|
|
29
|
+
throw new Error(`${path}: unknown key "${key}" (valid keys: ${FILE_KEYS.join(", ")})`);
|
|
30
|
+
}
|
|
30
31
|
}
|
|
31
32
|
if (file.$schema !== undefined && typeof file.$schema !== "string") {
|
|
32
33
|
throw new Error(`${path}: "$schema" must be a string`);
|
|
33
34
|
}
|
|
35
|
+
if (file.mcpServers !== undefined &&
|
|
36
|
+
(typeof file.mcpServers !== "object" || file.mcpServers === null || Array.isArray(file.mcpServers))) {
|
|
37
|
+
throw new Error(`${path}: "mcpServers" must be an object of servers by name`);
|
|
38
|
+
}
|
|
34
39
|
return file;
|
|
35
40
|
}
|
|
36
41
|
/** One part of `context.json` at `path`, declared by `declare`; its refusal names the file. */
|
|
@@ -45,24 +50,19 @@ function declarePart(path, declare) {
|
|
|
45
50
|
/** Read `text`, the contents of `path`, whole: what an edit, which writes the whole, reads. */
|
|
46
51
|
export function parseContextFile(text, path) {
|
|
47
52
|
const file = parseFile(text, path);
|
|
48
|
-
const declared = declarePart(path, () => declareContent(file.content));
|
|
53
|
+
const declared = declarePart(path, () => declareContent(file.content, { origin: "program", file: CONTEXT_FILE }));
|
|
49
54
|
const environment = declarePart(path, () => declareEnvironment(file.environment));
|
|
50
55
|
return {
|
|
51
56
|
...(file.$schema !== undefined ? { $schema: file.$schema } : {}),
|
|
52
57
|
content: (file.content ?? {}),
|
|
53
58
|
declared,
|
|
54
59
|
...(environment !== undefined ? { environment } : {}),
|
|
60
|
+
...(file.mcpServers !== undefined ? { mcpServers: file.mcpServers } : {}),
|
|
55
61
|
};
|
|
56
62
|
}
|
|
57
|
-
/**
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
const bound = declarePart(path, () => declareBindings(file.content, declared, resolve(agentDir)));
|
|
61
|
-
return { content: (file.content ?? {}), bound };
|
|
62
|
-
}
|
|
63
|
-
/** The agent's context file `name` and its path, or undefined text when it has none (it declares nothing). */
|
|
64
|
-
function contextFileAt(agentDir, name = CONTEXT_FILE) {
|
|
65
|
-
const path = join(resolve(agentDir), name);
|
|
63
|
+
/** The agent's `context.json` and its path, or undefined text when it has none (it declares nothing). */
|
|
64
|
+
function contextFileAt(agentDir) {
|
|
65
|
+
const path = join(resolve(agentDir), CONTEXT_FILE);
|
|
66
66
|
try {
|
|
67
67
|
return { path, text: readFileSync(path, "utf8") };
|
|
68
68
|
}
|
|
@@ -77,16 +77,25 @@ export function readContextFile(agentDir) {
|
|
|
77
77
|
const { path, text } = contextFileAt(agentDir);
|
|
78
78
|
return text === undefined ? { content: {}, declared: [] } : parseContextFile(text, path);
|
|
79
79
|
}
|
|
80
|
-
/**
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
/** The content of the agent in `agentDir`: what `context.json` declares, and what this machine binds. */
|
|
86
|
-
export function loadContent(agentDir) {
|
|
80
|
+
/**
|
|
81
|
+
* The content of the agent whose program is in `agentDir`: what its `context.json` declares, and what `instance` adds
|
|
82
|
+
* to it (an instance only adds: a name both declare is refused).
|
|
83
|
+
*/
|
|
84
|
+
export function loadContent(agentDir, instance) {
|
|
87
85
|
const { path, text } = contextFileAt(agentDir);
|
|
88
|
-
const
|
|
89
|
-
|
|
86
|
+
const program = text === undefined
|
|
87
|
+
? []
|
|
88
|
+
: declarePart(path, () => declareContent(parseFile(text, path).content, { origin: "program", file: CONTEXT_FILE }));
|
|
89
|
+
return joinContent(program, instance === undefined ? [] : instanceContent(instance));
|
|
90
|
+
}
|
|
91
|
+
/** What an instance configuration's `content` declares. */
|
|
92
|
+
export function instanceContent({ values, label, directory }) {
|
|
93
|
+
const content = typeof values === "object" && values !== null ? values.content : undefined;
|
|
94
|
+
return declarePart(label, () => declareContent(content, {
|
|
95
|
+
origin: "instance",
|
|
96
|
+
file: label,
|
|
97
|
+
...(directory === undefined ? {} : { base: directory }),
|
|
98
|
+
}));
|
|
90
99
|
}
|
|
91
100
|
/** The environment the agent in `agentDir` declares, or undefined when it declares none. */
|
|
92
101
|
export function loadEnvironment(agentDir) {
|
|
@@ -96,6 +105,11 @@ export function loadEnvironment(agentDir) {
|
|
|
96
105
|
const file = parseFile(text, path);
|
|
97
106
|
return declarePart(path, () => declareEnvironment(file.environment));
|
|
98
107
|
}
|
|
108
|
+
/** The program's `mcpServers` map as written in `context.json`, and the file's path, which names it in a refusal. */
|
|
109
|
+
export function readProgramMcpServers(agentDir) {
|
|
110
|
+
const { path, text } = contextFileAt(agentDir);
|
|
111
|
+
return { values: text === undefined ? undefined : parseFile(text, path).mcpServers, path };
|
|
112
|
+
}
|
|
99
113
|
/** The text `context.json` is written as. An environment that declares nothing is left out. */
|
|
100
114
|
export function contextFileText(file) {
|
|
101
115
|
const packages = file.environment?.packages ?? {};
|
|
@@ -110,10 +124,9 @@ export function contextFileText(file) {
|
|
|
110
124
|
...(file.$schema !== undefined ? { $schema: file.$schema } : {}),
|
|
111
125
|
content: file.content,
|
|
112
126
|
...(Object.keys(environment).length > 0 ? { environment } : {}),
|
|
127
|
+
...(file.mcpServers !== undefined && Object.keys(file.mcpServers).length > 0
|
|
128
|
+
? { mcpServers: file.mcpServers }
|
|
129
|
+
: {}),
|
|
113
130
|
};
|
|
114
131
|
return `${JSON.stringify(out, null, 2)}\n`;
|
|
115
132
|
}
|
|
116
|
-
/** The text `context.local.json` is written as. */
|
|
117
|
-
export function localContextFileText(content) {
|
|
118
|
-
return `${JSON.stringify({ content }, null, 2)}\n`;
|
|
119
|
-
}
|
package/dist/content/git.d.ts
CHANGED
|
@@ -8,16 +8,6 @@ export declare function checkoutOf(dir: string): {
|
|
|
8
8
|
root: string;
|
|
9
9
|
origin?: string;
|
|
10
10
|
} | undefined;
|
|
11
|
-
/**
|
|
12
|
-
* Why the directory `local` cannot stand for github `repo` on this machine, or undefined when it can: it is the root
|
|
13
|
-
* of a checkout whose `origin` is that repository.
|
|
14
|
-
*/
|
|
15
|
-
export declare function checkoutProblem(local: string, repo: string): string | undefined;
|
|
16
|
-
/**
|
|
17
|
-
* What to say when the checkout `dir` is not at `ref`, or undefined when it is: on that branch, or at the commit `ref`
|
|
18
|
-
* names. FastAgent never moves a checkout the user owns, so this is said, not acted on.
|
|
19
|
-
*/
|
|
20
|
-
export declare function refNotice(dir: string, ref: string): string | undefined;
|
|
21
11
|
/**
|
|
22
12
|
* What a start did with a clone: made it, moved it to what the remote has now, found it there already, or kept it as
|
|
23
13
|
* it is, for the `reason` given (git refused to touch the agent's work, or the remote could not be reached).
|
package/dist/content/git.js
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
* `ref`, and a clone, made or brought up to date in place. git's own configuration applies throughout (credential helpers, `url.<base>.insteadOf`), so
|
|
4
4
|
* a private repository is reached the way the user's own `git clone` reaches it.
|
|
5
5
|
*/
|
|
6
|
-
import { existsSync, mkdirSync,
|
|
6
|
+
import { existsSync, mkdirSync, renameSync, rmSync, statSync } from "node:fs";
|
|
7
7
|
import { basename, dirname, join } from "node:path";
|
|
8
8
|
import { gitFor } from "../git.js";
|
|
9
9
|
const WHY = "github content needs it on this machine";
|
|
10
|
-
const { answer:
|
|
10
|
+
const { answer: checkoutAnswer } = gitFor(WHY);
|
|
11
11
|
/** The `owner/repo` a GitHub remote URL names, in any of its spellings (https, ssh, scp-like), or undefined. */
|
|
12
12
|
export function githubRepoOf(url) {
|
|
13
13
|
const match = /^(?:(?:https?|git|ssh):\/\/(?:[^@/]+@)?github\.com\/|(?:[^@/:]+@)?github\.com:)([\w.-]+)\/([\w.-]+?)(?:\.git)?\/?$/i.exec(url.trim());
|
|
@@ -24,46 +24,12 @@ function githubUrl(repo) {
|
|
|
24
24
|
export function checkoutOf(dir) {
|
|
25
25
|
if (!existsSync(dir) || !statSync(dir).isDirectory())
|
|
26
26
|
return undefined;
|
|
27
|
-
const root =
|
|
27
|
+
const root = checkoutAnswer(["rev-parse", "--show-toplevel"], dir);
|
|
28
28
|
if (root === undefined)
|
|
29
29
|
return undefined;
|
|
30
|
-
const origin =
|
|
30
|
+
const origin = checkoutAnswer(["config", "--get", "remote.origin.url"], root);
|
|
31
31
|
return { root, ...(origin ? { origin } : {}) };
|
|
32
32
|
}
|
|
33
|
-
/**
|
|
34
|
-
* Why the directory `local` cannot stand for github `repo` on this machine, or undefined when it can: it is the root
|
|
35
|
-
* of a checkout whose `origin` is that repository.
|
|
36
|
-
*/
|
|
37
|
-
export function checkoutProblem(local, repo) {
|
|
38
|
-
if (!existsSync(local))
|
|
39
|
-
return "does not exist";
|
|
40
|
-
const checkout = checkoutOf(local);
|
|
41
|
-
if (checkout === undefined)
|
|
42
|
-
return "is not a git checkout";
|
|
43
|
-
if (realpathSync(checkout.root) !== realpathSync(local))
|
|
44
|
-
return `is inside the checkout ${checkout.root}, not its root`;
|
|
45
|
-
const of = checkout.origin === undefined ? undefined : githubRepoOf(checkout.origin);
|
|
46
|
-
if (of?.toLowerCase() !== repo.toLowerCase()) {
|
|
47
|
-
return `is a checkout of ${checkout.origin ?? "no origin"}, not of github ${repo}`;
|
|
48
|
-
}
|
|
49
|
-
return undefined;
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* What to say when the checkout `dir` is not at `ref`, or undefined when it is: on that branch, or at the commit `ref`
|
|
53
|
-
* names. FastAgent never moves a checkout the user owns, so this is said, not acted on.
|
|
54
|
-
*/
|
|
55
|
-
export function refNotice(dir, ref) {
|
|
56
|
-
const branch = gitAnswer(["symbolic-ref", "--quiet", "--short", "HEAD"], dir);
|
|
57
|
-
if (branch === ref)
|
|
58
|
-
return undefined;
|
|
59
|
-
const head = gitAnswer(["rev-parse", "HEAD"], dir);
|
|
60
|
-
const target = gitAnswer(["rev-parse", "--verify", "--quiet", "--end-of-options", `${ref}^{commit}`], dir);
|
|
61
|
-
if (head !== undefined && head === target) {
|
|
62
|
-
return undefined;
|
|
63
|
-
}
|
|
64
|
-
const at = branch ?? `a detached ${head?.slice(0, 7) ?? "HEAD"}`;
|
|
65
|
-
return `the checkout is on ${at}, declared ${ref}; it is left as it is`;
|
|
66
|
-
}
|
|
67
33
|
/** A commit named in full: fetched by its hash, since `clone --branch` takes only a branch or a tag. */
|
|
68
34
|
const FULL_COMMIT = /^[0-9a-f]{40}$/i;
|
|
69
35
|
/**
|
|
@@ -97,7 +63,7 @@ const HELPER_KEY = "credential.https://github.com.helper";
|
|
|
97
63
|
*/
|
|
98
64
|
export async function refreshClone(repo, ref, dir, env = process.env) {
|
|
99
65
|
// The agent's environment, whose GITHUB_TOKEN the clone's credential helper reads.
|
|
100
|
-
const { run: runGit } = gitFor(WHY, env);
|
|
66
|
+
const { run: runGit, answer: gitAnswer } = gitFor(WHY, env);
|
|
101
67
|
// A library caller can hand this anything; git reads a leading "-" as an option, and no repository or ref has one
|
|
102
68
|
// (a declaration with one is refused at load, declare.ts).
|
|
103
69
|
if (repo.startsWith("-") || ref?.startsWith("-")) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type DeclaredContent } from "./declare.ts";
|
|
2
2
|
import { type CloneOutcome } from "./git.ts";
|
|
3
3
|
/** A content entry, resolved for this instance. */
|
|
4
4
|
export type ResolvedContent = {
|
|
@@ -8,42 +8,38 @@ export type ResolvedContent = {
|
|
|
8
8
|
description?: string;
|
|
9
9
|
/** Where the agent reaches it on this instance, absolute. */
|
|
10
10
|
location: string;
|
|
11
|
-
/** What to tell the user about how it resolved: a
|
|
11
|
+
/** What to tell the user about how it resolved: a clone not made yet. */
|
|
12
12
|
notices: string[];
|
|
13
13
|
} & ({
|
|
14
|
-
/** A directory
|
|
14
|
+
/** A directory of this machine, where the instance configuration says. */
|
|
15
15
|
kind: "local";
|
|
16
16
|
} | {
|
|
17
|
+
/** A clone fastagent makes at `content/<name>` and brings up to date at each start while it holds nothing of the agent's. */
|
|
17
18
|
kind: "github";
|
|
18
19
|
/** `owner/repo`. */
|
|
19
20
|
repo: string;
|
|
20
21
|
ref?: string;
|
|
21
|
-
/**
|
|
22
|
-
* A clone fastagent makes at `content/<name>` and brings up to date at each start while it holds nothing of the
|
|
23
|
-
* agent's. False when this machine binds its own checkout, which is never touched.
|
|
24
|
-
*/
|
|
25
|
-
clone: boolean;
|
|
26
22
|
});
|
|
23
|
+
/** The directories an instance's content is kept apart from. */
|
|
24
|
+
export interface ContentPlaces {
|
|
25
|
+
/** The definition's own directory, which is released and read as it is. */
|
|
26
|
+
dir: string;
|
|
27
|
+
/** The instance's working directory, where clones are made. */
|
|
28
|
+
workdir: string;
|
|
29
|
+
}
|
|
27
30
|
/** Resolve the agent's content for this instance. Refuses, naming the entry, what cannot be. */
|
|
28
|
-
export declare function resolveContent(
|
|
31
|
+
export declare function resolveContent(declared: readonly DeclaredContent[], places: ContentPlaces): ResolvedContent[];
|
|
29
32
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
+
* Whether the content `name` can be the directory `target` of this machine: one that exists, and is apart from the
|
|
34
|
+
* definition's directory, since a definition is released, content is kept, and one directory cannot be both. The
|
|
35
|
+
* working directory is the instance's own writable place, so a directory inside it is only a directory the agent
|
|
36
|
+
* already reaches. Refuses, naming the entry, what cannot be.
|
|
33
37
|
*/
|
|
34
|
-
export declare function
|
|
35
|
-
/** What is said of a binding {@link contentAbsentHere} returns, after the word "content". */
|
|
36
|
-
export declare function absentNotice(binding: BoundContent): string;
|
|
37
|
-
/**
|
|
38
|
-
* Whether the content `name` can be bound to the directory `target` of this machine: a directory, apart from the agent
|
|
39
|
-
* directory, and for a declared repository the root of a checkout of it. Returns what to tell the user (a checkout off
|
|
40
|
-
* its `ref`); refuses, naming the entry, what cannot be.
|
|
41
|
-
*/
|
|
42
|
-
export declare function checkBinding(agentDir: string, name: string, target: string, repository?: Pick<DeclaredContent, "repo" | "ref">): string[];
|
|
38
|
+
export declare function checkDirectory({ dir }: Pick<ContentPlaces, "dir">, name: string, target: string): void;
|
|
43
39
|
/**
|
|
44
40
|
* Make a clone real, or bring it up to date at its `ref` in place, by git's rules, which never overwrite what the
|
|
45
41
|
* agent did in it (git.ts `refreshClone`): what git refuses, or a remote that cannot be reached, keeps it as it is,
|
|
46
|
-
* with the reason. Only a process that runs the agent calls this.
|
|
42
|
+
* with the reason. Only a process that runs the agent calls this.
|
|
47
43
|
*/
|
|
48
44
|
export declare function cloneContent(entry: Extract<ResolvedContent, {
|
|
49
45
|
kind: "github";
|