@ashulab/agent-forge 0.3.0 → 0.5.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.
- package/README.md +27 -10
- package/dist/launcher.cjs +106 -63
- package/package.json +1 -1
- package/schema/agents.schema.json +6 -9
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ On each run the launcher:
|
|
|
9
9
|
- detects installed provider CLIs on your PATH
|
|
10
10
|
- asks which provider to use (or takes it from a flag)
|
|
11
11
|
- starts the provider with the GitHub token and a per-agent git identity injected into the environment
|
|
12
|
-
-
|
|
12
|
+
- injects an identity prompt per process — a fixed block naming the git author identity and the `GH_TOKEN` / `GITHUB_TOKEN` in the environment, with the agent's optional `systemPrompt` appended (`claude --append-system-prompt`, `codex -c developer_instructions`; antigravity via a global custom agent selected with `--agent`) — no repo file is touched
|
|
13
13
|
|
|
14
14
|
Provider auth stays in the provider CLI — the launcher never handles provider API keys.
|
|
15
15
|
|
|
@@ -60,9 +60,10 @@ The shape, for reference — the `"$schema"` line points at the published schema
|
|
|
60
60
|
}
|
|
61
61
|
```
|
|
62
62
|
|
|
63
|
-
- The **installation id is not stored** — it is resolved on each run, in order: the owner of the repo you launch in, then
|
|
64
|
-
-
|
|
65
|
-
- `installationId` is
|
|
63
|
+
- The **installation id is not stored** — it is resolved on each run, in order: the owner of the repo you launch in, then the App's sole installation. So the same agent works across every org the App is installed on, and it survives an uninstall/reinstall (which rotates the id).
|
|
64
|
+
- An App installed on more than one account only resolves when you launch from inside a repo it covers — that repo picks the installation.
|
|
65
|
+
- `installationId` is accepted as an explicit override — set it to pin a specific id or skip the lookup (offline, or in a git credential helper).
|
|
66
|
+
- One agent, many accounts: a **private** GitHub App only installs on the account that owns it. To run the agent on both a personal account and an org, make the App public or use one App per account — see [docs/github-app.md](docs/github-app.md).
|
|
66
67
|
- `botId` is optional. When omitted it is resolved from the GitHub API using `botName` so the git author email links commits to the bot. Set it explicitly only to skip that lookup (e.g. offline).
|
|
67
68
|
- Do not put provider-specific config here — providers are auto-detected from PATH.
|
|
68
69
|
|
|
@@ -93,17 +94,19 @@ On launch, `agent-forge` prints the scope GitHub actually granted (`scope` row i
|
|
|
93
94
|
|
|
94
95
|
You need a GitHub App first — its **App ID**, a **private key**, and an **installation**. If you don't have one yet, follow [docs/github-app.md](docs/github-app.md).
|
|
95
96
|
|
|
97
|
+
Running `agent-forge` with no agents configured offers to run the wizard for you.
|
|
98
|
+
|
|
96
99
|
### Guided (recommended)
|
|
97
100
|
|
|
98
101
|
```bash
|
|
99
102
|
agent-forge add
|
|
100
103
|
```
|
|
101
104
|
|
|
102
|
-
You provide the **GitHub App ID** and the **path to its private key**. The wizard derives the rest from the GitHub API — slug (`botName`), bot user id
|
|
105
|
+
You provide the **GitHub App ID** and the **path to its private key**. The wizard derives the rest from the GitHub API — slug (`botName`), bot user id — asks for a label and an optional system prompt, mints a test token to confirm it works, and writes the entry. It writes to the resolved config path — the global registry (`~/.config/agent-forge/agents.json`) unless `$AGENT_FORGE_CONFIG` or an existing `./agents.json` redirects it.
|
|
103
106
|
|
|
104
107
|
### Manual
|
|
105
108
|
|
|
106
|
-
Copy one agent object inside the `agents` array and set unique values for `name`, `label`, `appId`, `botName`, `privateKeyPath
|
|
109
|
+
Copy one agent object inside the `agents` array and set unique values for `name`, `label`, `appId`, `botName`, `privateKeyPath`. Make sure the private key file exists and is readable.
|
|
107
110
|
|
|
108
111
|
## Launch
|
|
109
112
|
|
|
@@ -113,13 +116,26 @@ Interactive:
|
|
|
113
116
|
agent-forge
|
|
114
117
|
```
|
|
115
118
|
|
|
116
|
-
Direct flags (passing both skips
|
|
119
|
+
Direct flags (passing both skips the menus; passing one pre-fills it, the other is prompted — or auto-picked when only one agent or provider is available):
|
|
117
120
|
|
|
118
121
|
```bash
|
|
119
122
|
agent-forge --agent ops-agent --provider claude
|
|
120
123
|
agent-forge --agent review-agent --provider codex
|
|
121
124
|
```
|
|
122
125
|
|
|
126
|
+
Before launching, it prints a summary:
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
│ provider claude
|
|
130
|
+
│ identity ops-agent[bot]
|
|
131
|
+
│ account AshuLab ← which account the token is for
|
|
132
|
+
│ repo AshuLab/app ← the repo you're in (drives account)
|
|
133
|
+
│ scope write: contents, issues, pull_requests · +4 read
|
|
134
|
+
│ expires ~59m ← installation tokens last ~1h
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
(The `antigravity` provider adds an `agent` row showing the `--agent` id and the custom-agent file it wrote.)
|
|
138
|
+
|
|
123
139
|
Other commands:
|
|
124
140
|
|
|
125
141
|
```bash
|
|
@@ -130,10 +146,11 @@ agent-forge --help
|
|
|
130
146
|
|
|
131
147
|
### Provider-specific prompt behavior
|
|
132
148
|
|
|
133
|
-
|
|
134
|
-
- `codex` / `antigravity` (`agy`): no CLI flag — identity comes from `AGENTS.md` only (`agy --prompt` is headless `--print`; a codex positional arg is a fake first user turn)
|
|
149
|
+
The identity prompt (identity block + the agent's optional `systemPrompt`) is injected per process — no repo file is touched:
|
|
135
150
|
|
|
136
|
-
|
|
151
|
+
- `claude`: `--append-system-prompt` (lands in the real system prompt)
|
|
152
|
+
- `codex`: `-c developer_instructions=…` (appends a developer message; unlike `model_instructions_file` it does not replace codex's base prompt)
|
|
153
|
+
- `antigravity` (`agy`): no prompt flag — the launcher writes the identity prompt as a global antigravity custom agent at `~/.gemini/config/agents/<name>/agent.md` (frontmatter `name`, `mainAgent: true`, `agentForge: true`; prompt under an `# Identity` heading) and passes `--agent <name>`. The file is keyed by the agent's registry `name`, upserted on each run, and never deleted. If a file with that name exists without our `agentForge` marker, the launch fails rather than overwrite it — rename the agent or remove that file.
|
|
137
154
|
|
|
138
155
|
## Token refresh
|
|
139
156
|
|
package/dist/launcher.cjs
CHANGED
|
@@ -4016,7 +4016,6 @@ var require_jsonwebtoken = __commonJS({
|
|
|
4016
4016
|
|
|
4017
4017
|
// src/launcher.js
|
|
4018
4018
|
var import_node_child_process3 = require("node:child_process");
|
|
4019
|
-
var import_node_path4 = require("node:path");
|
|
4020
4019
|
var import_node_util4 = require("node:util");
|
|
4021
4020
|
|
|
4022
4021
|
// node_modules/.pnpm/@clack+core@1.4.3/node_modules/@clack/core/dist/index.mjs
|
|
@@ -5220,6 +5219,7 @@ var import_node_fs = require("node:fs");
|
|
|
5220
5219
|
var import_node_os = require("node:os");
|
|
5221
5220
|
var import_node_path = require("node:path");
|
|
5222
5221
|
var REQUIRED_FIELDS = ["name", "appId", "privateKeyPath"];
|
|
5222
|
+
var VALID_NAME = /^[a-z0-9][a-z0-9-]*$/;
|
|
5223
5223
|
var SCHEMA_URL = "https://raw.githubusercontent.com/AshuLab/agent-forge/main/schema/agents.schema.json";
|
|
5224
5224
|
var CONFIG_HOME = process.env.XDG_CONFIG_HOME || (0, import_node_path.join)((0, import_node_os.homedir)(), ".config");
|
|
5225
5225
|
var GLOBAL_CONFIG = (0, import_node_path.join)(CONFIG_HOME, "agent-forge", "agents.json");
|
|
@@ -5264,6 +5264,11 @@ function validateAgents(agents) {
|
|
|
5264
5264
|
throw new Error(`agents.json: agent ${ref} is missing "${field}"`);
|
|
5265
5265
|
}
|
|
5266
5266
|
}
|
|
5267
|
+
if (!VALID_NAME.test(agent.name)) {
|
|
5268
|
+
throw new Error(
|
|
5269
|
+
`agents.json: agent ${ref} has an invalid name "${agent.name}" (lowercase letters, digits, hyphens)`
|
|
5270
|
+
);
|
|
5271
|
+
}
|
|
5267
5272
|
if (seen.has(agent.name)) {
|
|
5268
5273
|
throw new Error(`agents.json: duplicate agent name "${agent.name}"`);
|
|
5269
5274
|
}
|
|
@@ -5377,19 +5382,9 @@ function pickInstallation(installations, agent) {
|
|
|
5377
5382
|
if (installations.length === 0) {
|
|
5378
5383
|
throw new Error(`GitHub App ${agent.appId} has no installations. Install it on an account or org first.`);
|
|
5379
5384
|
}
|
|
5380
|
-
if (agent.account) {
|
|
5381
|
-
const want = String(agent.account).toLowerCase();
|
|
5382
|
-
const match = installations.find((item) => item.account.toLowerCase() === want);
|
|
5383
|
-
if (!match) {
|
|
5384
|
-
throw new Error(
|
|
5385
|
-
`GitHub App ${agent.appId} is not installed on "${agent.account}". Installed on: ${installations.map((item) => item.account).join(", ")}.`
|
|
5386
|
-
);
|
|
5387
|
-
}
|
|
5388
|
-
return match.id;
|
|
5389
|
-
}
|
|
5390
5385
|
if (installations.length === 1) return installations[0].id;
|
|
5391
5386
|
throw new Error(
|
|
5392
|
-
`GitHub App ${agent.appId} is installed on ${installations.length} accounts (${installations.map((item) => item.account).join(", ")}).
|
|
5387
|
+
`GitHub App ${agent.appId} is installed on ${installations.length} accounts (${installations.map((item) => item.account).join(", ")}). Launch from inside a repo under one of them.`
|
|
5393
5388
|
);
|
|
5394
5389
|
}
|
|
5395
5390
|
function parseGithubRemote(url) {
|
|
@@ -5479,44 +5474,83 @@ function getProviderInfo(providerName, agent) {
|
|
|
5479
5474
|
const resolvedCommand = isCommandInstalled(command) ? command : (provider.aliases || []).find((alias) => isCommandInstalled(alias)) || command;
|
|
5480
5475
|
return { provider, command: resolvedCommand };
|
|
5481
5476
|
}
|
|
5482
|
-
function getProviderPromptArgs(providerName,
|
|
5483
|
-
|
|
5484
|
-
if (
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5477
|
+
function getProviderPromptArgs(providerName, prompt) {
|
|
5478
|
+
if (providerName === "claude") return ["--append-system-prompt", prompt];
|
|
5479
|
+
if (providerName === "codex") return ["-c", `developer_instructions=${JSON.stringify(prompt)}`];
|
|
5480
|
+
return [];
|
|
5481
|
+
}
|
|
5482
|
+
function buildProviderArgs(providerName, prompt, antigravityAgent) {
|
|
5483
|
+
return [
|
|
5484
|
+
...getProviderPromptArgs(providerName, prompt),
|
|
5485
|
+
...antigravityAgent ? ["--agent", antigravityAgent.name] : []
|
|
5486
|
+
];
|
|
5488
5487
|
}
|
|
5489
5488
|
|
|
5490
|
-
// src/
|
|
5489
|
+
// src/agent-file.js
|
|
5491
5490
|
var import_node_fs3 = require("node:fs");
|
|
5491
|
+
var import_node_os3 = require("node:os");
|
|
5492
5492
|
var import_node_path3 = require("node:path");
|
|
5493
|
-
var
|
|
5494
|
-
var
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
${prompt}
|
|
5499
|
-
${END}`;
|
|
5500
|
-
const start = content.indexOf(START);
|
|
5501
|
-
const end = content.indexOf(END);
|
|
5502
|
-
if (start !== -1 && end > start) {
|
|
5503
|
-
return content.slice(0, start) + block2 + content.slice(end + END.length);
|
|
5504
|
-
}
|
|
5505
|
-
return content ? `${content.trimEnd()}
|
|
5506
|
-
|
|
5507
|
-
${block2}
|
|
5508
|
-
` : `${block2}
|
|
5509
|
-
`;
|
|
5493
|
+
var MARKER = "agentForge: true";
|
|
5494
|
+
var MARKER_LINE = /^agentForge:\s*true\s*$/m;
|
|
5495
|
+
function isManagedByAgentForge(text2) {
|
|
5496
|
+
const end = text2.startsWith("---\n") ? text2.indexOf("\n---", 4) : -1;
|
|
5497
|
+
return end !== -1 && MARKER_LINE.test(text2.slice(0, end));
|
|
5510
5498
|
}
|
|
5511
|
-
|
|
5512
|
-
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
5499
|
+
var AGENTS_HOME = (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".gemini", "config", "agents");
|
|
5500
|
+
var VALID_NAME2 = /^[a-z0-9][a-z0-9-]*$/;
|
|
5501
|
+
function renderAgentFile(name, description, prompt) {
|
|
5502
|
+
return [
|
|
5503
|
+
"---",
|
|
5504
|
+
`name: ${name}`,
|
|
5505
|
+
`description: ${JSON.stringify(description)}`,
|
|
5506
|
+
"mainAgent: true",
|
|
5507
|
+
MARKER,
|
|
5508
|
+
"---",
|
|
5509
|
+
"",
|
|
5510
|
+
"# Identity",
|
|
5511
|
+
"",
|
|
5512
|
+
prompt.trimEnd(),
|
|
5513
|
+
""
|
|
5514
|
+
].join("\n");
|
|
5515
|
+
}
|
|
5516
|
+
function syncAntigravityAgent(agent, prompt, agentsHome = AGENTS_HOME) {
|
|
5517
|
+
const name = agent.name;
|
|
5518
|
+
if (!VALID_NAME2.test(name)) {
|
|
5519
|
+
throw new Error(
|
|
5520
|
+
`Agent name "${name}" is not a valid antigravity agent id (lowercase letters, digits, hyphens).`
|
|
5521
|
+
);
|
|
5522
|
+
}
|
|
5523
|
+
const dir = (0, import_node_path3.join)(agentsHome, name);
|
|
5524
|
+
const file = (0, import_node_path3.join)(dir, "agent.md");
|
|
5525
|
+
const next = renderAgentFile(name, agent.label || "GitHub App identity managed by agent-forge", prompt);
|
|
5526
|
+
if ((0, import_node_fs3.existsSync)(file)) {
|
|
5527
|
+
const current = (0, import_node_fs3.readFileSync)(file, "utf8");
|
|
5528
|
+
if (!isManagedByAgentForge(current)) {
|
|
5529
|
+
throw new Error(
|
|
5530
|
+
`${file} already exists and is not managed by agent-forge.
|
|
5531
|
+
Rename the agent in your registry or remove that file.`
|
|
5532
|
+
);
|
|
5533
|
+
}
|
|
5534
|
+
if (next !== current) (0, import_node_fs3.writeFileSync)(file, next);
|
|
5535
|
+
return { file, name };
|
|
5536
|
+
}
|
|
5537
|
+
(0, import_node_fs3.mkdirSync)(dir, { recursive: true });
|
|
5538
|
+
(0, import_node_fs3.writeFileSync)(file, next);
|
|
5539
|
+
return { file, name };
|
|
5540
|
+
}
|
|
5541
|
+
|
|
5542
|
+
// src/identity-prompt.js
|
|
5543
|
+
function buildIdentityPrompt({ name, email }, agentPrompt) {
|
|
5544
|
+
const base = [
|
|
5545
|
+
"You are operating under a GitHub App identity that agent-forge set up for this session; a human is driving it interactively.",
|
|
5546
|
+
"",
|
|
5547
|
+
`Your commits are authored as \`${name}\` <${email}> \u2014 already configured via GIT_AUTHOR_*/GIT_COMMITTER_*, do not change it.`,
|
|
5548
|
+
"A scoped, short-lived GitHub App installation token is available in the environment as GH_TOKEN and GITHUB_TOKEN; use it for `gh` and authenticated `git` operations."
|
|
5549
|
+
].join("\n");
|
|
5550
|
+
const own = agentPrompt?.trim();
|
|
5551
|
+
return own ? `${base}
|
|
5552
|
+
|
|
5553
|
+
${own}` : base;
|
|
5520
5554
|
}
|
|
5521
5555
|
|
|
5522
5556
|
// src/format.js
|
|
@@ -5542,7 +5576,7 @@ var import_node_util3 = require("node:util");
|
|
|
5542
5576
|
// package.json
|
|
5543
5577
|
var package_default = {
|
|
5544
5578
|
name: "@ashulab/agent-forge",
|
|
5545
|
-
version: "0.
|
|
5579
|
+
version: "0.5.0",
|
|
5546
5580
|
description: "Give claude/codex/antigravity their own GitHub identity: a bot account, a scoped token minted per run, git attribution to match",
|
|
5547
5581
|
license: "MIT",
|
|
5548
5582
|
author: "Diego Ghersi <ghersidl@gmail.com>",
|
|
@@ -5664,19 +5698,25 @@ async function addAgentWizard({ embedded = false } = {}) {
|
|
|
5664
5698
|
if (meta.installations.length === 0) {
|
|
5665
5699
|
throw new Error("This App has no installations. Install it on an account or org first.");
|
|
5666
5700
|
}
|
|
5667
|
-
|
|
5668
|
-
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
})
|
|
5676
|
-
);
|
|
5677
|
-
}
|
|
5678
|
-
const name = (keep(await text({ message: "Agent name", placeholder: meta.slug, defaultValue: meta.slug })) || meta.slug).trim();
|
|
5701
|
+
const where = meta.installations.length === 1 ? `${meta.installations[0].account} \u2014 resolved automatically each run` : `${meta.installations.map((i2) => i2.account).join(", ")} \u2014 resolved from the repo you launch in`;
|
|
5702
|
+
note(where, "Installation");
|
|
5703
|
+
const name = (keep(await text({
|
|
5704
|
+
message: "Agent name",
|
|
5705
|
+
placeholder: meta.slug,
|
|
5706
|
+
defaultValue: meta.slug,
|
|
5707
|
+
validate: (v) => /^[a-z0-9][a-z0-9-]*$/.test(v.trim()) ? void 0 : "Lowercase letters, digits, hyphens"
|
|
5708
|
+
})) || meta.slug).trim();
|
|
5679
5709
|
const label = (keep(await text({ message: "Label", placeholder: meta.name, defaultValue: meta.name })) || meta.name).trim();
|
|
5710
|
+
note(
|
|
5711
|
+
[
|
|
5712
|
+
"agent-forge already tells every launched agent:",
|
|
5713
|
+
" \xB7 its bot git identity (GIT_AUTHOR_*/GIT_COMMITTER_*)",
|
|
5714
|
+
" \xB7 that a scoped GH_TOKEN / GITHUB_TOKEN is in the environment",
|
|
5715
|
+
"",
|
|
5716
|
+
"Add only what is specific to this agent \u2014 role, style, guardrails."
|
|
5717
|
+
].join("\n"),
|
|
5718
|
+
"Identity is handled for you"
|
|
5719
|
+
);
|
|
5680
5720
|
const systemPrompt = keep(await text({ message: "System prompt (optional)", placeholder: "You are ..." })).trim();
|
|
5681
5721
|
const agent = {
|
|
5682
5722
|
name,
|
|
@@ -5684,7 +5724,6 @@ async function addAgentWizard({ embedded = false } = {}) {
|
|
|
5684
5724
|
appId,
|
|
5685
5725
|
botName: meta.slug,
|
|
5686
5726
|
privateKeyPath,
|
|
5687
|
-
...account ? { account } : {},
|
|
5688
5727
|
...systemPrompt ? { systemPrompt } : {}
|
|
5689
5728
|
};
|
|
5690
5729
|
const check = spinner();
|
|
@@ -5805,7 +5844,11 @@ async function launchAgent(agentName, providerName) {
|
|
|
5805
5844
|
const botId = await resolveBotId(agent);
|
|
5806
5845
|
const gitIdentity = buildGitIdentity(agent, botId);
|
|
5807
5846
|
s.stop(`Token ready for ${(0, import_node_util4.styleText)("green", gitIdentity.GIT_AUTHOR_NAME)}`);
|
|
5808
|
-
const
|
|
5847
|
+
const identityPrompt = buildIdentityPrompt(
|
|
5848
|
+
{ name: gitIdentity.GIT_AUTHOR_NAME, email: gitIdentity.GIT_AUTHOR_EMAIL },
|
|
5849
|
+
agent.systemPrompt || agent.instructions || agent.identityPrompt
|
|
5850
|
+
);
|
|
5851
|
+
const antigravityAgent = providerName === "antigravity" ? syncAntigravityAgent(agent, identityPrompt) : null;
|
|
5809
5852
|
const runtimeEnv = {
|
|
5810
5853
|
...process.env,
|
|
5811
5854
|
GITHUB_TOKEN: githubToken,
|
|
@@ -5826,11 +5869,11 @@ async function launchAgent(agentName, providerName) {
|
|
|
5826
5869
|
row("scope", (0, import_node_util4.styleText)("dim", repositorySelection === "selected" ? `${scopeText} \xB7 selected repos` : scopeText))
|
|
5827
5870
|
);
|
|
5828
5871
|
if (expiresAt) summary.push(row("expires", (0, import_node_util4.styleText)("dim", formatExpiry(expiresAt))));
|
|
5829
|
-
if (
|
|
5830
|
-
summary.push(row("
|
|
5872
|
+
if (antigravityAgent) {
|
|
5873
|
+
summary.push(row("agent", (0, import_node_util4.styleText)("dim", `--agent ${antigravityAgent.name} \xB7 ${antigravityAgent.file}`)));
|
|
5831
5874
|
}
|
|
5832
5875
|
note(summary.join("\n"), (0, import_node_util4.styleText)("bold", agent.label || agent.name));
|
|
5833
|
-
const providerArgs =
|
|
5876
|
+
const providerArgs = buildProviderArgs(providerName, identityPrompt, antigravityAgent);
|
|
5834
5877
|
const child = (0, import_node_child_process3.spawn)(providerInfo.command, providerArgs, {
|
|
5835
5878
|
stdio: "inherit",
|
|
5836
5879
|
env: runtimeEnv,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ashulab/agent-forge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Give claude/codex/antigravity their own GitHub identity: a bot account, a scoped token minted per run, git attribution to match",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Diego Ghersi <ghersidl@gmail.com>",
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
"properties": {
|
|
16
16
|
"name": {
|
|
17
17
|
"type": "string",
|
|
18
|
-
"
|
|
18
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$",
|
|
19
|
+
"description": "Unique agent id, used with --agent. Lowercase letters, digits, hyphens (also the antigravity custom-agent id)."
|
|
19
20
|
},
|
|
20
21
|
"label": {
|
|
21
22
|
"type": "string",
|
|
@@ -25,13 +26,9 @@
|
|
|
25
26
|
"type": "string",
|
|
26
27
|
"description": "GitHub App ID (numeric, stored as a string)"
|
|
27
28
|
},
|
|
28
|
-
"account": {
|
|
29
|
-
"type": "string",
|
|
30
|
-
"description": "Account/org login where the App is installed. Fallback for installation-id resolution when you run outside a matching repo. Needed only when the App has more than one installation. Resolution order: repo owner, then account, then the sole installation."
|
|
31
|
-
},
|
|
32
29
|
"installationId": {
|
|
33
30
|
"type": "string",
|
|
34
|
-
"description": "Optional override. Normally the installation id is resolved (repo owner, then
|
|
31
|
+
"description": "Optional override. Normally the installation id is resolved (repo owner, then the App's sole installation). Set this to pin a specific id or skip the lookup (offline, or in a git credential helper)."
|
|
35
32
|
},
|
|
36
33
|
"botName": {
|
|
37
34
|
"type": "string",
|
|
@@ -47,15 +44,15 @@
|
|
|
47
44
|
},
|
|
48
45
|
"systemPrompt": {
|
|
49
46
|
"type": "string",
|
|
50
|
-
"description": "
|
|
47
|
+
"description": "Optional agent-specific system prompt, appended to the identity block agent-forge always injects. Per process: claude --append-system-prompt, codex developer_instructions, antigravity a global custom agent selected with --agent"
|
|
51
48
|
},
|
|
52
49
|
"instructions": {
|
|
53
50
|
"type": "string",
|
|
54
|
-
"description": "Fallback
|
|
51
|
+
"description": "Fallback for systemPrompt when it is absent; same identity-block + append behavior"
|
|
55
52
|
},
|
|
56
53
|
"identityPrompt": {
|
|
57
54
|
"type": "string",
|
|
58
|
-
"description": "Fallback
|
|
55
|
+
"description": "Fallback for systemPrompt and instructions when both are absent; same identity-block + append behavior"
|
|
59
56
|
},
|
|
60
57
|
"repositories": {
|
|
61
58
|
"type": "array",
|