@rsaglobaltech/specgate 0.16.0 → 0.17.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/CHANGELOG.md +27 -0
- package/dist/packages/core/src/application/GenerateAgentPromptUseCase.js +10 -1
- package/dist/packages/core/src/application/GenerateAgentPromptUseCase.js.map +1 -1
- package/dist/packages/core/src/domain/AgentPrompt.js +2 -2
- package/dist/packages/core/src/domain/AgentPrompt.js.map +1 -1
- package/dist/packages/core/src/domain/MultiStack.js +2 -2
- package/dist/packages/core/src/domain/MultiStack.js.map +1 -1
- package/dist/packages/core/src/domain/WriteScope.js +1 -0
- package/dist/packages/core/src/domain/WriteScope.js.map +1 -1
- package/dist/scripts/agents/commands.js +2 -2
- package/dist/scripts/agents/commands.js.map +1 -1
- package/dist/scripts/agents/contract-file.js +165 -0
- package/dist/scripts/agents/contract-file.js.map +1 -0
- package/dist/scripts/agents/detect.js +97 -0
- package/dist/scripts/agents/detect.js.map +1 -0
- package/dist/scripts/agents/init.js +59 -35
- package/dist/scripts/agents/init.js.map +1 -1
- package/dist/scripts/change/instructions.js +14 -6
- package/dist/scripts/change/instructions.js.map +1 -1
- package/dist/scripts/cli/commands/project/AdoptCommand.js +42 -5
- package/dist/scripts/cli/commands/project/AdoptCommand.js.map +1 -1
- package/dist/scripts/cli/commands/project/InitProjectCommand.js +39 -6
- package/dist/scripts/cli/commands/project/InitProjectCommand.js.map +1 -1
- package/dist/scripts/cli/commands/project/UpdateCommand.js +18 -3
- package/dist/scripts/cli/commands/project/UpdateCommand.js.map +1 -1
- package/dist/scripts/cli/commands/quality/DoctorCommand.js +11 -6
- package/dist/scripts/cli/commands/quality/DoctorCommand.js.map +1 -1
- package/dist/scripts/cli/commands/quality/ValidateSpecsCommand.js +5 -2
- package/dist/scripts/cli/commands/quality/ValidateSpecsCommand.js.map +1 -1
- package/dist/scripts/cli/commands/specops/SyncCommand.js +21 -1
- package/dist/scripts/cli/commands/specops/SyncCommand.js.map +1 -1
- package/package.json +1 -1
- package/templates/adopt/stack-rules.md +3 -0
- package/templates/backend/stack-rules.md +2 -0
- package/templates/base/AGENTS.md.tpl +30 -32
- package/templates/frontend/stack-rules.md +2 -0
- package/templates/mobile/stack-rules.md +7 -0
- package/templates/adopt/AI_RULES.md.tpl +0 -27
- package/templates/backend/AI_RULES.md.tpl +0 -35
- package/templates/frontend/AI_RULES.md.tpl +0 -34
- package/templates/mobile/AI_RULES.md.tpl +0 -56
package/CHANGELOG.md
CHANGED
|
@@ -8,7 +8,34 @@ The release process is in [`docs/release-process.md`](docs/release-process.md).
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [0.17.0] — 2026-10-09
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **`specops sync` that changes nothing leaves `.specops.lock` alone.** It
|
|
16
|
+
rewrote each pack's `expanded_at` on every run, so a no-op sync left a diff
|
|
17
|
+
to commit or revert. The timestamp now moves only when the pack's repo,
|
|
18
|
+
version, commit or variables do.
|
|
19
|
+
|
|
11
20
|
## [0.16.0] — 2026-10-09
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **`AGENTS.md` is the agent contract; `AI_RULES.md` folds into it**
|
|
24
|
+
(ADR-0031). `init` and `adopt` write one short `AGENTS.md` — the file
|
|
25
|
+
Codex, Cursor, Copilot and most agents read — with the commands, the loop,
|
|
26
|
+
what never to do and the stack's rules, instead of an `AI_RULES.md`, an
|
|
27
|
+
"Agent Manifest" and `agents init`'s instructions that overlapped. Specgate
|
|
28
|
+
keeps its part in a marked block; a team's own `AGENTS.md` text is never
|
|
29
|
+
rewritten. `specgate update` moves an existing `AI_RULES.md` below the block,
|
|
30
|
+
verbatim. Until then both are read, so no rule drops out of the agent's
|
|
31
|
+
prompt; `validate` and `doctor` accept either.
|
|
32
|
+
|
|
33
|
+
- **`specgate init` installs the `/specgate:*` commands for the agents your
|
|
34
|
+
project already uses** — Claude Code (`.claude/`, `CLAUDE.md`), Cursor,
|
|
35
|
+
Copilot, Gemini, Windsurf, Cline, Aider, Codex, Antigravity — and only for
|
|
36
|
+
those, never overwriting a file. With none found it says how to add one.
|
|
37
|
+
`--no-agents` skips it. The developer talks to the agent they already have
|
|
38
|
+
from the first minute, without `agents init` to discover.
|
|
12
39
|
|
|
13
40
|
### Added
|
|
14
41
|
|
|
@@ -18,7 +18,15 @@ class GenerateAgentPromptUseCase {
|
|
|
18
18
|
const featureContent = featurePath
|
|
19
19
|
? this.configRepo.readProjectFile(projectDir, featurePath)
|
|
20
20
|
: null;
|
|
21
|
-
|
|
21
|
+
// AGENTS.md is the agent contract (ADR-0031). Until `specgate update`
|
|
22
|
+
// folds a team's AI_RULES.md into it, both are read: the team's rules must
|
|
23
|
+
// not drop out of the prompt because AGENTS.md appeared.
|
|
24
|
+
const agentsMd = this.configRepo.readProjectFile(projectDir, "AGENTS.md");
|
|
25
|
+
const legacyRules = this.configRepo.readProjectFile(projectDir, "AI_RULES.md");
|
|
26
|
+
const aiRulesContent = [agentsMd, legacyRules].filter(Boolean).join("\n\n") || null;
|
|
27
|
+
const rulesFile = [agentsMd && "AGENTS.md", legacyRules && "AI_RULES.md"]
|
|
28
|
+
.filter(Boolean)
|
|
29
|
+
.join(" + ");
|
|
22
30
|
// The requirement's own prose. Not reading it is how the prompt came to say
|
|
23
31
|
// "Implement REQ-002" with every fact `-` and nothing to implement.
|
|
24
32
|
const specSource = this.configRepo.readProjectFile(projectDir, "spec.md");
|
|
@@ -42,6 +50,7 @@ class GenerateAgentPromptUseCase {
|
|
|
42
50
|
...opts,
|
|
43
51
|
featureContent,
|
|
44
52
|
aiRulesContent,
|
|
53
|
+
rulesFile,
|
|
45
54
|
requirementText: requirementText || undefined,
|
|
46
55
|
otherScenarios,
|
|
47
56
|
// Opt-in: the caller decides, because a precedent costs prompt budget and
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GenerateAgentPromptUseCase.js","sourceRoot":"","sources":["../../../../../packages/core/src/application/GenerateAgentPromptUseCase.ts"],"names":[],"mappings":";;;AACA,uDAAsF;AACtF,qDAAuD;AACvD,qDAA8E;AAC9E,yDAAmE;AACnE,qEAKsC;AAEtC,MAAM,MAAM,GAAG,4BAA4B,CAAC;AAC5C,MAAM,YAAY,GAAG,yBAAyB,CAAC;AAE/C,MAAa,0BAA0B;IACjB;IAApB,YAAoB,UAAoC;QAApC,eAAU,GAAV,UAAU,CAA0B;IAAG,CAAC;IAErD,OAAO,CAAC,GAAsB,EAAE,UAAkB,EAAE,OAAsB,EAAE;QACjF,MAAM,WAAW,GAAG,IAAA,4BAAe,EAAC,GAAG,CAAC,IAAI,IAAI,CAAC;QACjD,MAAM,cAAc,GAAG,WAAW;YAChC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,UAAU,EAAE,WAAW,CAAC;YAC1D,CAAC,CAAC,IAAI,CAAC;QACT,MAAM,
|
|
1
|
+
{"version":3,"file":"GenerateAgentPromptUseCase.js","sourceRoot":"","sources":["../../../../../packages/core/src/application/GenerateAgentPromptUseCase.ts"],"names":[],"mappings":"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"}
|
|
@@ -73,7 +73,7 @@ class AgentPrompt {
|
|
|
73
73
|
parts.push(AgentPrompt.section(`Another scenario of this requirement (${other.path})`, "```gherkin\n" + other.content.trimEnd() + "\n```"));
|
|
74
74
|
}
|
|
75
75
|
if (opts.aiRulesContent) {
|
|
76
|
-
parts.push(AgentPrompt.section(
|
|
76
|
+
parts.push(AgentPrompt.section(`Project rules (${opts.rulesFile || "AGENTS.md"} — non-negotiable)`, opts.aiRulesContent.trimEnd()));
|
|
77
77
|
}
|
|
78
78
|
if (opts.precedent && (opts.precedent.testExcerpt || opts.precedent.technicalExcerpt)) {
|
|
79
79
|
const p = opts.precedent;
|
|
@@ -101,7 +101,7 @@ class AgentPrompt {
|
|
|
101
101
|
];
|
|
102
102
|
const doneRules = [
|
|
103
103
|
...baseRules,
|
|
104
|
-
"**Do not modify** `spec.md`, `AI_RULES.md
|
|
104
|
+
"**Do not modify** `spec.md`, `AGENTS.md` (or `AI_RULES.md`), or any existing `features/**/*.feature` — " +
|
|
105
105
|
"they are the contract you are being judged against. Creating a feature file that " +
|
|
106
106
|
"does not exist yet is not modifying one, and the gate allows it: an agent asked " +
|
|
107
107
|
"to write a missing scenario is not being asked to break this rule.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentPrompt.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/AgentPrompt.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"AgentPrompt.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/AgentPrompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* describes behaviour, which is the point of writing it in Gherkin. But the
|
|
10
10
|
* traceability matrix maps a requirement to the file that implements it and the
|
|
11
11
|
* file that proves it, and those are different files in every stack — so the
|
|
12
|
-
* matrix cannot be shared, and neither can
|
|
12
|
+
* matrix cannot be shared, and neither can AGENTS.md, which is the rulebook
|
|
13
13
|
* for one toolchain.
|
|
14
14
|
*
|
|
15
15
|
* Sharing the first set and splitting the second is the whole design. Copying
|
|
@@ -24,7 +24,7 @@ exports.relativeToRoot = relativeToRoot;
|
|
|
24
24
|
/** Paths that are one artifact for the whole tree, held at the root. */
|
|
25
25
|
exports.SHARED_PATHS = ["spec.md", "features", "docs/specs/adr"];
|
|
26
26
|
/** Paths each stack owns outright — they name files that differ per toolchain. */
|
|
27
|
-
exports.PER_STACK_PATHS = ["
|
|
27
|
+
exports.PER_STACK_PATHS = ["AGENTS.md", "README.md", "docs/specs/traceability.md"];
|
|
28
28
|
class InvalidStackList extends Error {
|
|
29
29
|
}
|
|
30
30
|
exports.InvalidStackList = InvalidStackList;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultiStack.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/MultiStack.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;;;AA6BH,gCAmCC;AAQD,kDAYC;AAUD,wCAGC;AA/FD,wEAAwE;AAC3D,QAAA,YAAY,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,gBAAgB,CAAU,CAAC;AAE/E,kFAAkF;AACrE,QAAA,eAAe,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"MultiStack.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/MultiStack.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WriteScope.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/WriteScope.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;;;
|
|
1
|
+
{"version":3,"file":"WriteScope.js","sourceRoot":"","sources":["../../../../../packages/core/src/domain/WriteScope.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,7 +20,7 @@ exports.STEPS = [
|
|
|
20
20
|
when: "Starting work, or unsure what to do next.",
|
|
21
21
|
run: ["specgate status --json"],
|
|
22
22
|
guidance: [
|
|
23
|
-
"Read `spec.md` and `
|
|
23
|
+
"Read `spec.md` and `AGENTS.md` first — `AGENTS.md` is binding, not advisory.",
|
|
24
24
|
"`requirements` lists each one with what it still needs; `nextCommand` names the step.",
|
|
25
25
|
"Do not start on a requirement until you can say which `REQ-NNN` it is.",
|
|
26
26
|
],
|
|
@@ -114,7 +114,7 @@ exports.STEPS = [
|
|
|
114
114
|
];
|
|
115
115
|
/** The rules every tool's instruction file repeats, in its own format. */
|
|
116
116
|
exports.PROJECT_RULES = [
|
|
117
|
-
"`spec.md`, `
|
|
117
|
+
"`spec.md`, `AGENTS.md` and `features/**/*.feature` are the source of truth. Do not edit them to make a test pass.",
|
|
118
118
|
"`docs/specs/traceability.md` is generated — never edit it. A test or source file that names `REQ-NNN` is linked to that requirement; that is how work is traced.",
|
|
119
119
|
"Every command takes `--json`. Use it: one document on stdout, diagnostics in `status`, each with a `fix`.",
|
|
120
120
|
"Exit codes are a contract: 0 success, 1 failure or gate finding, 2 usage error.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../scripts/agents/commands.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AAEU,QAAA,KAAK,GAAG;IACnB;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,oDAAoD;QAC7D,IAAI,EAAE,2CAA2C;QACjD,GAAG,EAAE,CAAC,wBAAwB,CAAC;QAC/B,QAAQ,EAAE;YACR,
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../scripts/agents/commands.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AAEU,QAAA,KAAK,GAAG;IACnB;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,oDAAoD;QAC7D,IAAI,EAAE,2CAA2C;QACjD,GAAG,EAAE,CAAC,wBAAwB,CAAC;QAC/B,QAAQ,EAAE;YACR,8EAA8E;YAC9E,uFAAuF;YACvF,wEAAwE;SACzE;KACF;IACD;QACE,IAAI,EAAE,KAAK;QACX,OAAO,EAAE,sEAAsE;QAC/E,IAAI,EAAE,+DAA+D;QACrE,GAAG,EAAE,CAAC,iDAAiD,CAAC;QACxD,QAAQ,EAAE;YACR,gHAAgH;YAChH,qJAAqJ;YACrJ,0CAA0C;SAC3C;KACF;IACD;QACE,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,2DAA2D;QACpE,IAAI,EAAE,8DAA8D;QACpE,GAAG,EAAE,CAAC,wBAAwB,EAAE,2CAA2C,CAAC;QAC5E,QAAQ,EAAE;YACR,oDAAoD;YACpD,6JAA6J;YAC7J,4FAA4F;YAC5F,6DAA6D;SAC9D;KACF;IACD;QACE,sEAAsE;QACtE,sEAAsE;QACtE,8DAA8D;QAC9D,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,+DAA+D;QACxE,IAAI,EAAE,yDAAyD;QAC/D,GAAG,EAAE,CAAC,uBAAuB,CAAC;QAC9B,QAAQ,EAAE;YACR,kEAAkE;YAClE,kFAAkF;YAClF,yFAAyF;SAC1F;KACF;IACD;QACE,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,uCAAuC;QAChD,IAAI,EAAE,+DAA+D;QACrE,GAAG,EAAE,CAAC,yCAAyC,CAAC;QAChD,QAAQ,EAAE;YACR,2GAA2G;YAC3G,0EAA0E;SAC3E;KACF;IACD;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,mEAAmE;QAC5E,IAAI,EAAE,qFAAqF;QAC3F,GAAG,EAAE;YACH,iCAAiC;YACjC,8CAA8C;YAC9C,2CAA2C;SAC5C;QACD,QAAQ,EAAE;YACR,4JAA4J;YAC5J,iEAAiE;YACjE,mIAAmI;SACpI;KACF;IACD;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,8CAA8C;QACvD,IAAI,EAAE,sDAAsD;QAC5D,GAAG,EAAE;YACH,6CAA6C;YAC7C,+CAA+C;YAC/C,4CAA4C;SAC7C;QACD,QAAQ,EAAE;YACR,oEAAoE;YACpE,+FAA+F;SAChG;KACF;IACD;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,gEAAgE;QACzE,IAAI,EAAE,2CAA2C;QACjD,GAAG,EAAE,CAAC,eAAe,EAAE,uBAAuB,CAAC;QAC/C,QAAQ,EAAE;YACR,yGAAyG;YACzG,4GAA4G;SAC7G;KACF;CACF,CAAC;AAEF,0EAA0E;AAC7D,QAAA,aAAa,GAAG;IAC3B,mHAAmH;IACnH,kKAAkK;IAClK,2GAA2G;IAC3G,iFAAiF;IACjF,2HAA2H;CAC5H,CAAC"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AGENTS.md as a shared file (ADR-0031).
|
|
4
|
+
*
|
|
5
|
+
* The market's agents read one `AGENTS.md`, and a team often has one before
|
|
6
|
+
* Specgate arrives. Specgate's contract therefore lives in a marked block:
|
|
7
|
+
* created when the file is new, inserted above the team's text when it is
|
|
8
|
+
* not, and replaced in place — and only that block — on every later run.
|
|
9
|
+
* The team's text outside the markers is never rewritten.
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.END = exports.BEGIN = void 0;
|
|
46
|
+
exports.mergeContract = mergeContract;
|
|
47
|
+
exports.outsideBlock = outsideBlock;
|
|
48
|
+
exports.rulesField = rulesField;
|
|
49
|
+
exports.writtenByOlderSpecgate = writtenByOlderSpecgate;
|
|
50
|
+
exports.buildContract = buildContract;
|
|
51
|
+
exports.ensureContract = ensureContract;
|
|
52
|
+
exports.migrateAiRules = migrateAiRules;
|
|
53
|
+
const fs = __importStar(require("node:fs"));
|
|
54
|
+
const path = __importStar(require("node:path"));
|
|
55
|
+
const project_root_1 = require("../lib/project-root");
|
|
56
|
+
exports.BEGIN = "<!-- specgate:begin — generated by specgate; edit outside this block -->";
|
|
57
|
+
exports.END = "<!-- specgate:end -->";
|
|
58
|
+
/** `existing` with the block set to `contract`. */
|
|
59
|
+
function mergeContract(existing, contract) {
|
|
60
|
+
const block = `${exports.BEGIN}\n${contract.trimEnd()}\n${exports.END}\n`;
|
|
61
|
+
if (existing === null || existing.trim() === "")
|
|
62
|
+
return block;
|
|
63
|
+
const start = existing.indexOf(exports.BEGIN.slice(0, 22));
|
|
64
|
+
const end = existing.indexOf(exports.END);
|
|
65
|
+
if (start !== -1 && end !== -1 && end > start) {
|
|
66
|
+
return existing.slice(0, start) + block + existing.slice(end + exports.END.length).replace(/^\n/, "");
|
|
67
|
+
}
|
|
68
|
+
return `${block}\n${existing}`;
|
|
69
|
+
}
|
|
70
|
+
/** The team's text: everything outside the block. */
|
|
71
|
+
function outsideBlock(existing) {
|
|
72
|
+
const start = existing.indexOf(exports.BEGIN.slice(0, 22));
|
|
73
|
+
const end = existing.indexOf(exports.END);
|
|
74
|
+
if (start === -1 || end === -1 || end < start)
|
|
75
|
+
return existing;
|
|
76
|
+
return (existing.slice(0, start) + existing.slice(end + exports.END.length)).trim();
|
|
77
|
+
}
|
|
78
|
+
// ── The contract, for a project `init` did not write it for ─────────────────
|
|
79
|
+
/** `- Stack: x` (AI_RULES.md) or `… · Stack: x · …` (AGENTS.md). */
|
|
80
|
+
function rulesField(text, name) {
|
|
81
|
+
const m = new RegExp(`(?:^|·)\\s*-?\\s*\\**${name}:?\\**:?\\s*([^·\\n]+)`, "im").exec(text);
|
|
82
|
+
return m ? m[1].trim() : null;
|
|
83
|
+
}
|
|
84
|
+
/** `# AI Rules — golden-app` / `# AI Rules - Backend (Shop)` / `# Agent Manifest — Shop`. */
|
|
85
|
+
function titleName(text) {
|
|
86
|
+
const m = /^#\s+(?:AI[ _]Rules|Agent Manifest)\s*[—–-]\s*(?:\w+\s*\(([^)]+)\)|(.+))$/im.exec(text);
|
|
87
|
+
return m ? (m[1] || m[2]).trim() : null;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Text an older Specgate generated into AGENTS.md — `agents init`'s
|
|
91
|
+
* instructions, `init`'s "Agent Manifest". It is replaced whole by the block;
|
|
92
|
+
* a team's own AGENTS.md has neither sentence, and is kept.
|
|
93
|
+
*/
|
|
94
|
+
const OLDER_SPECGATE = [
|
|
95
|
+
"This project uses Spec-Driven Development through the `specgate` CLI.",
|
|
96
|
+
"This file helps AI coding agents (Claude, Copilot, Cursor, Aider, etc.)",
|
|
97
|
+
];
|
|
98
|
+
function writtenByOlderSpecgate(text) {
|
|
99
|
+
return OLDER_SPECGATE.some((sig) => text.includes(sig));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* The generated contract with the project's facts read from its existing
|
|
103
|
+
* rules file. The stack's rules stay where the team wrote them — `update`
|
|
104
|
+
* moves them below the block, verbatim — so the block's own rules section
|
|
105
|
+
* points there.
|
|
106
|
+
*/
|
|
107
|
+
function buildContract(facts, projectDir) {
|
|
108
|
+
const root = (0, project_root_1.findCliRoot)(__dirname);
|
|
109
|
+
const tpl = fs.readFileSync(path.join(root, "templates", "base", "AGENTS.md.tpl"), "utf8");
|
|
110
|
+
const vars = {
|
|
111
|
+
PROJECT_NAME: (rulesField(facts, "Project") ||
|
|
112
|
+
titleName(facts) ||
|
|
113
|
+
path.basename(path.resolve(projectDir))).replace(/\s*\(.*\)$/, ""),
|
|
114
|
+
PROJECT_TYPE: "existing",
|
|
115
|
+
ARCHITECTURE: rulesField(facts, "Architecture") || "minimal",
|
|
116
|
+
DOMAIN: rulesField(facts, "Domain") || "see spec.md",
|
|
117
|
+
STACK: rulesField(facts, "Stack") || "see below",
|
|
118
|
+
API_STYLE: rulesField(facts, "API style") || rulesField(facts, "API integration") || "as built",
|
|
119
|
+
TESTING: rulesField(facts, "Testing") || "see below",
|
|
120
|
+
STACK_RULES: "- The team's own rules follow this block.",
|
|
121
|
+
ARCHITECTURE_MODELING_RULES: "",
|
|
122
|
+
ARCHITECTURE_CHECKS: "",
|
|
123
|
+
};
|
|
124
|
+
return (tpl.replace(/\{\{([A-Z_]+)\}\}/g, (all, k) => (k in vars ? vars[k] : all)).trimEnd() + "\n");
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* `AGENTS.md` for a project: the block written when missing, inserted above
|
|
128
|
+
* the team's text when the file has none, left alone when it has one.
|
|
129
|
+
* Returns what happened, or null when nothing needed writing.
|
|
130
|
+
*/
|
|
131
|
+
function ensureContract(projectDir, opts = {}) {
|
|
132
|
+
const file = path.join(projectDir, "AGENTS.md");
|
|
133
|
+
const found = fs.existsSync(file) ? fs.readFileSync(file, "utf8") : null;
|
|
134
|
+
if (found !== null && found.includes(exports.BEGIN.slice(0, 22)))
|
|
135
|
+
return null;
|
|
136
|
+
// What an older Specgate generated is replaced, not kept below the block.
|
|
137
|
+
const older = found !== null && writtenByOlderSpecgate(found);
|
|
138
|
+
const existing = older ? null : found;
|
|
139
|
+
const legacy = path.join(projectDir, "AI_RULES.md");
|
|
140
|
+
const facts = [fs.existsSync(legacy) ? fs.readFileSync(legacy, "utf8") : "", found || ""].join("\n");
|
|
141
|
+
if (!opts.dryRun) {
|
|
142
|
+
fs.writeFileSync(file, mergeContract(existing, buildContract(facts, projectDir)), "utf8");
|
|
143
|
+
}
|
|
144
|
+
return older ? "replaced" : found === null ? "written" : "block-added";
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* ADR-0031's migration: AI_RULES.md's text moves, verbatim, below the block in
|
|
148
|
+
* AGENTS.md, and AI_RULES.md goes. Git keeps the old file; nothing is lost.
|
|
149
|
+
*/
|
|
150
|
+
function migrateAiRules(projectDir, opts = {}) {
|
|
151
|
+
const legacy = path.join(projectDir, "AI_RULES.md");
|
|
152
|
+
if (!fs.existsSync(legacy))
|
|
153
|
+
return { moved: false, agents: null };
|
|
154
|
+
const rules = fs.readFileSync(legacy, "utf8").trim();
|
|
155
|
+
const agents = ensureContract(projectDir, opts);
|
|
156
|
+
if (!opts.dryRun) {
|
|
157
|
+
const file = path.join(projectDir, "AGENTS.md");
|
|
158
|
+
const current = fs.readFileSync(file, "utf8").trimEnd();
|
|
159
|
+
const moved = rules.replace(/^#\s+.*\n+/, "");
|
|
160
|
+
fs.writeFileSync(file, `${current}\n\n## Project rules (from AI_RULES.md)\n\n${moved}\n`, "utf8");
|
|
161
|
+
fs.rmSync(legacy);
|
|
162
|
+
}
|
|
163
|
+
return { moved: true, agents };
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=contract-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-file.js","sourceRoot":"","sources":["../../../scripts/agents/contract-file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Which coding agents does this project already use? (simplification plan,
|
|
4
|
+
* phase 2: the agent is the interface)
|
|
5
|
+
*
|
|
6
|
+
* `init` and `adopt` install the `/specgate:*` commands for the agents they
|
|
7
|
+
* find, so the developer talks to the agent they already have from the first
|
|
8
|
+
* minute — without `agents init` to discover, and without files for ten
|
|
9
|
+
* agents nobody on the team uses.
|
|
10
|
+
*
|
|
11
|
+
* A marker is a file or directory that agent creates or reads. `AGENTS.md`
|
|
12
|
+
* alone is not one: several agents read it and it says nothing about which.
|
|
13
|
+
*/
|
|
14
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
17
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
18
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
19
|
+
}
|
|
20
|
+
Object.defineProperty(o, k2, desc);
|
|
21
|
+
}) : (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
o[k2] = m[k];
|
|
24
|
+
}));
|
|
25
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
26
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
27
|
+
}) : function(o, v) {
|
|
28
|
+
o["default"] = v;
|
|
29
|
+
});
|
|
30
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
31
|
+
var ownKeys = function(o) {
|
|
32
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
33
|
+
var ar = [];
|
|
34
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
35
|
+
return ar;
|
|
36
|
+
};
|
|
37
|
+
return ownKeys(o);
|
|
38
|
+
};
|
|
39
|
+
return function (mod) {
|
|
40
|
+
if (mod && mod.__esModule) return mod;
|
|
41
|
+
var result = {};
|
|
42
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
43
|
+
__setModuleDefault(result, mod);
|
|
44
|
+
return result;
|
|
45
|
+
};
|
|
46
|
+
})();
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.detectAgents = detectAgents;
|
|
49
|
+
exports.installDetectedAgents = installDetectedAgents;
|
|
50
|
+
const fs = __importStar(require("node:fs"));
|
|
51
|
+
const path = __importStar(require("node:path"));
|
|
52
|
+
const init_1 = require("./init");
|
|
53
|
+
const MARKERS = [
|
|
54
|
+
["claude", [".claude", "CLAUDE.md"]],
|
|
55
|
+
["cursor", [".cursor", ".cursorrules"]],
|
|
56
|
+
["copilot", [path.join(".github", "copilot-instructions.md")]],
|
|
57
|
+
["windsurf", [".windsurf", ".windsurfrules"]],
|
|
58
|
+
["aider", [".aider.conf.yml"]],
|
|
59
|
+
["gemini", [".gemini", "GEMINI.md"]],
|
|
60
|
+
["cline", [".clinerules"]],
|
|
61
|
+
["codex", [".codex"]],
|
|
62
|
+
["antigravity", [".agents"]],
|
|
63
|
+
];
|
|
64
|
+
function detectAgents(projectDir) {
|
|
65
|
+
return MARKERS.filter(([tool, files]) => init_1.TOOLS[tool] && files.some((f) => fs.existsSync(path.join(projectDir, f)))).map(([tool]) => tool);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* The last step of `init` and `adopt`: install for the detected agents, or say
|
|
69
|
+
* how to. Never overwrites a file, never fails the command it ends.
|
|
70
|
+
*/
|
|
71
|
+
function installDetectedAgents(projectDir, opts, log) {
|
|
72
|
+
if (opts.skip)
|
|
73
|
+
return;
|
|
74
|
+
let tools = [];
|
|
75
|
+
try {
|
|
76
|
+
tools = detectAgents(projectDir);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (tools.length === 0) {
|
|
82
|
+
log("Agent: none detected. To drive the daily loop from your agent:");
|
|
83
|
+
log(" specgate agents init --tool claude # or cursor, copilot, gemini, … (--help)");
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const { written, skipped } = (0, init_1.writeAgentFiles)(projectDir, tools, { dryRun: opts.dryRun });
|
|
88
|
+
const labels = tools.map((t) => init_1.TOOLS[t].label).join(", ");
|
|
89
|
+
log(`Agent: ${labels} — ${opts.dryRun ? "would install" : "installed"} the /specgate:* commands` +
|
|
90
|
+
` (${written.length} file(s)${skipped.length ? `, ${skipped.length} already there, left alone` : ""}).`);
|
|
91
|
+
log(" Ask your agent: /specgate:explore # what is left, and what to do next");
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
log(`Agent: could not install the commands (${err && err.message}); run \`specgate agents init\`.`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../../scripts/agents/detect.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBH,oCAIC;AAMD,sDA8BC;AAxDD,4CAA8B;AAC9B,gDAAkC;AAClC,iCAAgD;AAEhD,MAAM,OAAO,GAAsC;IACjD,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACpC,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACvC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,yBAAyB,CAAC,CAAC,CAAC;IAC9D,CAAC,UAAU,EAAE,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAC7C,CAAC,OAAO,EAAE,CAAC,iBAAiB,CAAC,CAAC;IAC9B,CAAC,QAAQ,EAAE,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACpC,CAAC,OAAO,EAAE,CAAC,aAAa,CAAC,CAAC;IAC1B,CAAC,OAAO,EAAE,CAAC,QAAQ,CAAC,CAAC;IACrB,CAAC,aAAa,EAAE,CAAC,SAAS,CAAC,CAAC;CAC7B,CAAC;AAEF,SAAgB,YAAY,CAAC,UAAkB;IAC7C,OAAO,OAAO,CAAC,MAAM,CACnB,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,YAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAC7F,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED;;;GAGG;AACH,SAAgB,qBAAqB,CACnC,UAAkB,EAClB,IAA0C,EAC1C,GAA0B;IAE1B,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO;IACtB,IAAI,KAAK,GAAa,EAAE,CAAC;IACzB,IAAI,CAAC;QACH,KAAK,GAAG,YAAY,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,GAAG,CAAC,gEAAgE,CAAC,CAAC;QACtE,GAAG,CAAC,iFAAiF,CAAC,CAAC;QACvF,OAAO;IACT,CAAC;IACD,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,IAAA,sBAAe,EAAC,UAAU,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACzF,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3D,GAAG,CACD,UAAU,MAAM,MAAM,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,WAAW,2BAA2B;YAC1F,KAAK,OAAO,CAAC,MAAM,WAAW,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,MAAM,4BAA4B,CAAC,CAAC,CAAC,EAAE,IAAI,CAC1G,CAAC;QACF,GAAG,CAAC,2EAA2E,CAAC,CAAC;IACnF,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,GAAG,CACD,0CAA0C,GAAG,IAAI,GAAG,CAAC,OAAO,kCAAkC,CAC/F,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -50,7 +50,9 @@ exports.instructionsBody = instructionsBody;
|
|
|
50
50
|
exports.mcpServerConfig = mcpServerConfig;
|
|
51
51
|
exports.renamedPaths = renamedPaths;
|
|
52
52
|
exports.parseArgs = parseArgs;
|
|
53
|
+
exports.writeAgentFiles = writeAgentFiles;
|
|
53
54
|
exports.main = main;
|
|
55
|
+
const contract_file_1 = require("./contract-file");
|
|
54
56
|
const fs = __importStar(require("node:fs"));
|
|
55
57
|
const path = __importStar(require("node:path"));
|
|
56
58
|
const project_root_1 = require("../lib/project-root");
|
|
@@ -440,6 +442,59 @@ function parseArgs(argv) {
|
|
|
440
442
|
}
|
|
441
443
|
return opts;
|
|
442
444
|
}
|
|
445
|
+
/**
|
|
446
|
+
* Write the files for `tools` into `projectDir`. An existing file is left
|
|
447
|
+
* untouched unless `force`. Shared by `agents init` and by `init`/`adopt`,
|
|
448
|
+
* which install for the agents they detect.
|
|
449
|
+
*/
|
|
450
|
+
function writeAgentFiles(projectDir, tools, opts = {}) {
|
|
451
|
+
const written = [];
|
|
452
|
+
const skipped = [];
|
|
453
|
+
const diagnostics = [];
|
|
454
|
+
// Several tools share a destination — Claude and Codex both read AGENTS.md —
|
|
455
|
+
// so a file is written once and attributed to the tools that asked for it.
|
|
456
|
+
const planned = new Map();
|
|
457
|
+
for (const tool of tools) {
|
|
458
|
+
for (const file of exports.TOOLS[tool].files()) {
|
|
459
|
+
const entry = planned.get(file.path);
|
|
460
|
+
if (entry)
|
|
461
|
+
entry.tools.push(tool);
|
|
462
|
+
else
|
|
463
|
+
planned.set(file.path, { ...file, tools: [tool] });
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
{
|
|
467
|
+
for (const file of planned.values()) {
|
|
468
|
+
const tool = file.tools.join("+");
|
|
469
|
+
// AGENTS.md is shared with the team and other tools: Specgate owns a
|
|
470
|
+
// marked block in it, never the whole file (ADR-0031).
|
|
471
|
+
if (file.path === "AGENTS.md") {
|
|
472
|
+
const done = (0, contract_file_1.ensureContract)(projectDir, { dryRun: opts.dryRun });
|
|
473
|
+
if (done)
|
|
474
|
+
written.push({ tool, path: file.path });
|
|
475
|
+
else
|
|
476
|
+
skipped.push({ tool, path: file.path, reason: "has the specgate block" });
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
const target = path.join(projectDir, file.path);
|
|
480
|
+
const exists = fs.existsSync(target);
|
|
481
|
+
if (exists && !opts.force) {
|
|
482
|
+
skipped.push({ tool, path: file.path, reason: "exists" });
|
|
483
|
+
diagnostics.push((0, diagnostics_1.warning)("agent_file_exists", `${file.path} already exists — left untouched.`, {
|
|
484
|
+
file: file.path,
|
|
485
|
+
fix: "Pass --force to overwrite it, or merge the generated content by hand.",
|
|
486
|
+
}));
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
489
|
+
if (!opts.dryRun) {
|
|
490
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
491
|
+
fs.writeFileSync(target, file.contents, "utf8");
|
|
492
|
+
}
|
|
493
|
+
written.push({ tool, path: file.path });
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
return { written, skipped, diagnostics };
|
|
497
|
+
}
|
|
443
498
|
function main(argv) {
|
|
444
499
|
const opts = parseArgs(argv);
|
|
445
500
|
const io = (0, agent_1.agentIo)(opts.json || (0, agent_1.wantsJson)(argv));
|
|
@@ -476,41 +531,10 @@ function main(argv) {
|
|
|
476
531
|
}),
|
|
477
532
|
]);
|
|
478
533
|
}
|
|
479
|
-
const written =
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
// so a file is written once and attributed to the tools that asked for it.
|
|
484
|
-
const planned = new Map();
|
|
485
|
-
for (const tool of opts.tools) {
|
|
486
|
-
for (const file of exports.TOOLS[tool].files()) {
|
|
487
|
-
const entry = planned.get(file.path);
|
|
488
|
-
if (entry)
|
|
489
|
-
entry.tools.push(tool);
|
|
490
|
-
else
|
|
491
|
-
planned.set(file.path, { ...file, tools: [tool] });
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
{
|
|
495
|
-
for (const file of planned.values()) {
|
|
496
|
-
const tool = file.tools.join("+");
|
|
497
|
-
const target = path.join(projectDir, file.path);
|
|
498
|
-
const exists = fs.existsSync(target);
|
|
499
|
-
if (exists && !opts.force) {
|
|
500
|
-
skipped.push({ tool, path: file.path, reason: "exists" });
|
|
501
|
-
diagnostics.push((0, diagnostics_1.warning)("agent_file_exists", `${file.path} already exists — left untouched.`, {
|
|
502
|
-
file: file.path,
|
|
503
|
-
fix: "Pass --force to overwrite it, or merge the generated content by hand.",
|
|
504
|
-
}));
|
|
505
|
-
continue;
|
|
506
|
-
}
|
|
507
|
-
if (!opts.dryRun) {
|
|
508
|
-
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
509
|
-
fs.writeFileSync(target, file.contents, "utf8");
|
|
510
|
-
}
|
|
511
|
-
written.push({ tool, path: file.path });
|
|
512
|
-
}
|
|
513
|
-
}
|
|
534
|
+
const { written, skipped, diagnostics } = writeAgentFiles(projectDir, opts.tools, {
|
|
535
|
+
force: opts.force,
|
|
536
|
+
dryRun: opts.dryRun,
|
|
537
|
+
});
|
|
514
538
|
io.emit({
|
|
515
539
|
agents: {
|
|
516
540
|
projectDir,
|