@event4u/agent-config 9.10.0 → 9.11.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/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +59 -0
- package/README.md +12 -15
- package/agents/templates/.ai-council.yml.example +481 -0
- package/agents/templates/.ai-video.xml.example +247 -0
- package/dist/agent-src/rules/design-fidelity.md +1 -1
- package/dist/agent-src/skills/existing-ui-audit/SKILL.md +15 -2
- package/dist/agent-src/skills/fe-design/SKILL.md +10 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +30 -30
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/design.ts +88 -33
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +20 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.ts +20 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +179 -0
- package/dist/agent-src/templates/scripts/work_engine/stack/detect.ts +155 -4
- package/dist/agent-src/templates/scripts/work_engine/state.ts +21 -4
- package/dist/cli/initRouting.js +74 -11
- package/dist/cli/initRouting.js.map +1 -1
- package/dist/cli/main.js +14 -3
- package/dist/cli/main.js.map +1 -1
- package/dist/cli-delegate/chunk-4SV3XGFA.js +6910 -0
- package/dist/cli-delegate/chunk-736JCWLM.js +1104 -0
- package/dist/cli-delegate/chunk-7DSAMZFU.js +356 -0
- package/dist/cli-delegate/chunk-7HQ52DHU.js +74 -0
- package/dist/cli-delegate/chunk-BJGXZNPM.js +266 -0
- package/dist/cli-delegate/chunk-FTAISGDQ.js +117 -0
- package/dist/cli-delegate/chunk-GME3Q44L.js +82 -0
- package/dist/cli-delegate/chunk-GRRPEPRN.js +336 -0
- package/dist/cli-delegate/chunk-HJ6DAJHR.js +502 -0
- package/dist/cli-delegate/chunk-IR7P7JWA.js +872 -0
- package/dist/cli-delegate/chunk-J55WI3RR.js +47 -0
- package/dist/cli-delegate/chunk-MCJYCQPF.js +35 -0
- package/dist/cli-delegate/chunk-NDJLNC6Q.js +169 -0
- package/dist/cli-delegate/chunk-OMIVVCG2.js +26 -0
- package/dist/cli-delegate/chunk-OY53J6II.js +7336 -0
- package/dist/cli-delegate/chunk-RDGRHAAB.js +259 -0
- package/dist/cli-delegate/chunk-TFG57JJM.js +1969 -0
- package/dist/cli-delegate/chunk-XX6TOPD7.js +715 -0
- package/dist/cli-delegate/chunk-YMFO6FDN.js +10603 -0
- package/dist/cli-delegate/cmd_analyze_session.js +294 -0
- package/dist/cli-delegate/cmd_conformance.js +646 -0
- package/dist/cli-delegate/cmd_converge.js +326 -0
- package/dist/cli-delegate/cmd_doctor.js +144 -0
- package/dist/cli-delegate/cmd_explain.js +2508 -0
- package/dist/cli-delegate/cmd_export.js +296 -0
- package/dist/cli-delegate/cmd_fleet.js +332 -0
- package/dist/cli-delegate/cmd_memory_get.js +3878 -0
- package/dist/cli-delegate/cmd_migrate.js +11 -0
- package/dist/cli-delegate/cmd_preflight.js +270 -0
- package/dist/cli-delegate/cmd_prune.js +444 -0
- package/dist/cli-delegate/cmd_refresh.js +28 -0
- package/dist/cli-delegate/cmd_settings_check.js +574 -0
- package/dist/cli-delegate/cmd_settings_migrate.js +223 -0
- package/dist/cli-delegate/cmd_sync.js +264 -0
- package/dist/cli-delegate/cmd_uninstall.js +656 -0
- package/dist/cli-delegate/cmd_update.js +425 -0
- package/dist/cli-delegate/cmd_upgrade.js +444 -0
- package/dist/cli-delegate/cmd_validate.js +305 -0
- package/dist/cli-delegate/cmd_versions.js +370 -0
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +14 -7
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +2 -2
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +12 -7
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +4 -3
- package/dist/install/emit_host_rules_cli.js +2 -1
- package/dist/install/emit_host_rules_cli.js.map +1 -1
- package/dist/install/install.mjs +410 -378
- package/dist/install/rule_scope.js +5 -1
- package/dist/install/rule_scope.js.map +1 -1
- package/dist/install/toolDetection.js +40 -12
- package/dist/install/toolDetection.js.map +1 -1
- package/dist/install/wizard-plan.js +2 -2
- package/dist/install/wizard-plan.js.map +1 -1
- package/dist/mcp/registry-manifest.json +1 -1
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +1614 -765
- package/dist/router.json +1 -1
- package/package.json +4 -2
- package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +30 -30
- package/src/agent-src/templates/scripts/work_engine/directives/ui/design.ts +88 -33
- package/src/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +20 -0
- package/src/agent-src/templates/scripts/work_engine/directives/ui/review.ts +20 -1
- package/src/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +179 -0
- package/src/agent-src/templates/scripts/work_engine/stack/detect.ts +155 -4
- package/src/agent-src/templates/scripts/work_engine/state.ts +21 -4
- package/src/config/discovery/packs.yml +7 -0
- package/src/config/evaluator-budgets.json +1 -1
- package/src/config/pack-size-budget.json +27 -0
- package/src/install/emit_host_rules_cli.ts +2 -1
- package/src/install/rule_scope.ts +5 -1
- package/src/install/toolDetection.ts +39 -8
- package/src/install/wizard-plan.ts +2 -2
- package/src/scripts/_cli/cmd_conformance.ts +2 -1
- package/src/scripts/_cli/cmd_converge.ts +2 -1
- package/src/scripts/_cli/cmd_doctor.ts +214 -13
- package/src/scripts/_cli/cmd_export.ts +2 -1
- package/src/scripts/_cli/cmd_fleet.ts +2 -1
- package/src/scripts/_cli/cmd_migrate.ts +2 -1
- package/src/scripts/_cli/cmd_preflight.ts +2 -1
- package/src/scripts/_cli/cmd_refresh.ts +2 -1
- package/src/scripts/_cli/cmd_update.ts +2 -1
- package/src/scripts/_cli/cmd_upgrade.ts +2 -1
- package/src/scripts/_cli/cmd_versions.ts +2 -1
- package/src/scripts/_cli/detection_report.ts +480 -0
- package/src/scripts/_dispatch.bash +52 -14
- package/src/scripts/_lib/changelog_eras.ts +103 -9
- package/src/scripts/_lib/environment_detector.ts +441 -0
- package/src/scripts/_lib/package_root.ts +72 -0
- package/src/scripts/ai_council/config.ts +15 -7
- package/src/scripts/ai_council/modes.ts +68 -2
- package/src/scripts/ai_council/transport_resolver.ts +331 -0
- package/src/scripts/check_bundle_path_leakage.ts +10 -4
- package/src/scripts/check_dependency_floors.ts +153 -0
- package/src/scripts/check_pack_size.ts +188 -0
- package/src/scripts/council_cli.ts +6 -2
- package/src/scripts/evaluator_umbrella.sh +34 -1
- package/src/scripts/lint_eval_fixture_citations.ts +113 -0
- package/src/scripts/lint_ui_stack_bundles.ts +170 -0
|
@@ -0,0 +1,1104 @@
|
|
|
1
|
+
import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
resolvePackageRoot
|
|
4
|
+
} from "./chunk-MCJYCQPF.js";
|
|
5
|
+
import {
|
|
6
|
+
__export
|
|
7
|
+
} from "./chunk-J55WI3RR.js";
|
|
8
|
+
|
|
9
|
+
// src/scripts/_cli/cmd_refresh.ts
|
|
10
|
+
import * as fs4 from "node:fs";
|
|
11
|
+
import * as path4 from "node:path";
|
|
12
|
+
import { spawnSync } from "node:child_process";
|
|
13
|
+
import process3 from "node:process";
|
|
14
|
+
import { fileURLToPath as fileURLToPath4, pathToFileURL as pathToFileURL3 } from "node:url";
|
|
15
|
+
|
|
16
|
+
// src/scripts/_lib/cli_wrapper.ts
|
|
17
|
+
import fs from "node:fs";
|
|
18
|
+
import path from "node:path";
|
|
19
|
+
import { fileURLToPath } from "node:url";
|
|
20
|
+
var _PACKAGE_ROOT = path.resolve(
|
|
21
|
+
path.dirname(fileURLToPath(import.meta.url)),
|
|
22
|
+
"..",
|
|
23
|
+
"..",
|
|
24
|
+
".."
|
|
25
|
+
);
|
|
26
|
+
var _TEMPLATE = path.join(
|
|
27
|
+
_PACKAGE_ROOT,
|
|
28
|
+
"src",
|
|
29
|
+
"templates",
|
|
30
|
+
"agent-config-wrapper.sh"
|
|
31
|
+
);
|
|
32
|
+
function _is_file(p) {
|
|
33
|
+
try {
|
|
34
|
+
return fs.statSync(p).isFile();
|
|
35
|
+
} catch {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function _target(project_root) {
|
|
40
|
+
return path.join(project_root, "agent-config");
|
|
41
|
+
}
|
|
42
|
+
function needs_refresh(project_root) {
|
|
43
|
+
if (!_is_file(_TEMPLATE)) return false;
|
|
44
|
+
const target = _target(project_root);
|
|
45
|
+
if (!_is_file(target)) return true;
|
|
46
|
+
try {
|
|
47
|
+
return fs.readFileSync(target, "utf-8") !== fs.readFileSync(_TEMPLATE, "utf-8");
|
|
48
|
+
} catch {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function install_cli_wrapper(project_root) {
|
|
53
|
+
if (!_is_file(_TEMPLATE)) return null;
|
|
54
|
+
const target = _target(project_root);
|
|
55
|
+
fs.copyFileSync(_TEMPLATE, target);
|
|
56
|
+
fs.chmodSync(target, 493);
|
|
57
|
+
return target;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// src/scripts/sync_gitignore.ts
|
|
61
|
+
var sync_gitignore_exports = {};
|
|
62
|
+
__export(sync_gitignore_exports, {
|
|
63
|
+
DEFAULT_GITIGNORE: () => DEFAULT_GITIGNORE,
|
|
64
|
+
DEFAULT_TEMPLATE: () => DEFAULT_TEMPLATE,
|
|
65
|
+
LEGACY_PATTERNS: () => LEGACY_PATTERNS,
|
|
66
|
+
SECTION_FOOTER: () => SECTION_FOOTER,
|
|
67
|
+
SECTION_HEADER: () => SECTION_HEADER,
|
|
68
|
+
TemplateNotFoundError: () => TemplateNotFoundError,
|
|
69
|
+
block_entries: () => block_entries,
|
|
70
|
+
build_fresh_block: () => build_fresh_block,
|
|
71
|
+
cleanup_legacy: () => cleanup_legacy,
|
|
72
|
+
find_block: () => find_block,
|
|
73
|
+
format_file: () => format_file,
|
|
74
|
+
load_template: () => load_template,
|
|
75
|
+
main: () => main,
|
|
76
|
+
render_diff: () => render_diff,
|
|
77
|
+
sync_block: () => sync_block,
|
|
78
|
+
template_entries: () => template_entries,
|
|
79
|
+
unified_diff: () => unified_diff
|
|
80
|
+
});
|
|
81
|
+
import * as fs2 from "node:fs";
|
|
82
|
+
import * as path2 from "node:path";
|
|
83
|
+
import process from "node:process";
|
|
84
|
+
import { fileURLToPath as fileURLToPath2, pathToFileURL } from "node:url";
|
|
85
|
+
var SECTION_HEADER = "# event4u/agent-config";
|
|
86
|
+
var SECTION_FOOTER = "# event4u/agent-config \u2014 END";
|
|
87
|
+
var DEFAULT_GITIGNORE = ".gitignore";
|
|
88
|
+
var _HERE = fileURLToPath2(import.meta.url);
|
|
89
|
+
var DEFAULT_TEMPLATE = path2.join(
|
|
90
|
+
path2.dirname(_HERE),
|
|
91
|
+
"..",
|
|
92
|
+
"..",
|
|
93
|
+
"src",
|
|
94
|
+
"config",
|
|
95
|
+
"gitignore-block.txt"
|
|
96
|
+
);
|
|
97
|
+
var LEGACY_PATTERNS = [
|
|
98
|
+
".agent-chat-history",
|
|
99
|
+
".agent-chat-history.bak",
|
|
100
|
+
".agent-chat-history.*.bak",
|
|
101
|
+
".agent-prices.md",
|
|
102
|
+
".council-tmp/",
|
|
103
|
+
// 2.x intermediate: prices cache lived directly under agents/ before
|
|
104
|
+
// consolidating under agents/runtime/.
|
|
105
|
+
"agents/.agent-prices.md",
|
|
106
|
+
// Budget history JSONLs — previously listed explicitly at project
|
|
107
|
+
// root or under agents/; now covered by the /agents/runtime/
|
|
108
|
+
// catch-all in the managed block.
|
|
109
|
+
".augment-budget-history.jsonl",
|
|
110
|
+
".rule-budget-history.jsonl",
|
|
111
|
+
"agents/.augment-budget-history.jsonl",
|
|
112
|
+
"agents/.rule-budget-history.jsonl"
|
|
113
|
+
];
|
|
114
|
+
function _strip(ln) {
|
|
115
|
+
return ln.replace(/\n+$/, "").replace(/\s+$/, "");
|
|
116
|
+
}
|
|
117
|
+
function _is_entry(ln) {
|
|
118
|
+
const s = _strip(ln).replace(/^\s+/, "");
|
|
119
|
+
return Boolean(s) && !s.startsWith("#");
|
|
120
|
+
}
|
|
121
|
+
var TemplateNotFoundError = class extends Error {
|
|
122
|
+
constructor(p) {
|
|
123
|
+
super(`template not found: ${p}`);
|
|
124
|
+
this.name = "TemplateNotFoundError";
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
function _isFile(p) {
|
|
128
|
+
try {
|
|
129
|
+
return fs2.statSync(p).isFile();
|
|
130
|
+
} catch {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function _splitlines(text) {
|
|
135
|
+
if (text === "") return [];
|
|
136
|
+
const parts = text.split(/\r\n|\r|\n/);
|
|
137
|
+
if (parts.length > 0 && parts[parts.length - 1] === "") parts.pop();
|
|
138
|
+
return parts;
|
|
139
|
+
}
|
|
140
|
+
function load_template(p) {
|
|
141
|
+
if (!_isFile(p)) {
|
|
142
|
+
throw new TemplateNotFoundError(p);
|
|
143
|
+
}
|
|
144
|
+
const text = fs2.readFileSync(p, "utf-8");
|
|
145
|
+
return _splitlines(text).map(_strip);
|
|
146
|
+
}
|
|
147
|
+
function find_block(lines) {
|
|
148
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
149
|
+
if (_strip(lines[i]) === SECTION_HEADER) {
|
|
150
|
+
const start = i;
|
|
151
|
+
for (let j = i + 1; j < lines.length; j += 1) {
|
|
152
|
+
if (_strip(lines[j]) === SECTION_FOOTER) {
|
|
153
|
+
return [start, j + 1];
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
let end = lines.length;
|
|
157
|
+
for (let j = i + 1; j < lines.length; j += 1) {
|
|
158
|
+
const s = _strip(lines[j]).replace(/^\s+/, "");
|
|
159
|
+
if (s.startsWith("#") && !s.startsWith("# Agent config") && s !== SECTION_HEADER) {
|
|
160
|
+
end = j;
|
|
161
|
+
while (end > i + 1 && _strip(lines[end - 1]) === "") {
|
|
162
|
+
end -= 1;
|
|
163
|
+
}
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return [start, end];
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
function block_entries(block_lines) {
|
|
173
|
+
return block_lines.filter((ln) => _is_entry(ln)).map((ln) => _strip(ln).replace(/^\s+/, ""));
|
|
174
|
+
}
|
|
175
|
+
function template_entries(template_lines) {
|
|
176
|
+
return template_lines.filter((ln) => _is_entry(ln)).map((ln) => ln.replace(/^\s+/, ""));
|
|
177
|
+
}
|
|
178
|
+
function build_fresh_block(template_lines) {
|
|
179
|
+
return [SECTION_HEADER, ...template_lines, SECTION_FOOTER];
|
|
180
|
+
}
|
|
181
|
+
function sync_block(existing_lines, template_lines, options = {}) {
|
|
182
|
+
const replace = options.replace ?? false;
|
|
183
|
+
const loc = find_block(existing_lines);
|
|
184
|
+
const fresh = build_fresh_block(template_lines);
|
|
185
|
+
if (loc === null) {
|
|
186
|
+
const newLines = [...existing_lines];
|
|
187
|
+
if (newLines.length > 0 && _strip(newLines[newLines.length - 1]) !== "") {
|
|
188
|
+
newLines.push("");
|
|
189
|
+
}
|
|
190
|
+
newLines.push(...fresh);
|
|
191
|
+
return [newLines, template_entries(template_lines)];
|
|
192
|
+
}
|
|
193
|
+
const [start, end] = loc;
|
|
194
|
+
const head = existing_lines.slice(0, start);
|
|
195
|
+
let block = existing_lines.slice(start, end);
|
|
196
|
+
const tail = existing_lines.slice(end);
|
|
197
|
+
if (replace) {
|
|
198
|
+
const existing = new Set(block_entries(block));
|
|
199
|
+
const added = template_entries(template_lines).filter((e) => !existing.has(e));
|
|
200
|
+
return [[...head, ...fresh, ...tail], added];
|
|
201
|
+
}
|
|
202
|
+
const existing_entries = new Set(block_entries(block));
|
|
203
|
+
const missing = template_entries(template_lines).filter((e) => !existing_entries.has(e));
|
|
204
|
+
if (missing.length === 0) {
|
|
205
|
+
return [[...existing_lines], []];
|
|
206
|
+
}
|
|
207
|
+
let insert_at;
|
|
208
|
+
if (block.length > 0 && _strip(block[block.length - 1]) === SECTION_FOOTER) {
|
|
209
|
+
insert_at = block.length - 1;
|
|
210
|
+
} else {
|
|
211
|
+
block = [...block, SECTION_FOOTER];
|
|
212
|
+
insert_at = block.length - 1;
|
|
213
|
+
}
|
|
214
|
+
const new_block = [...block.slice(0, insert_at), ...missing, ...block.slice(insert_at)];
|
|
215
|
+
return [[...head, ...new_block, ...tail], missing];
|
|
216
|
+
}
|
|
217
|
+
function cleanup_legacy(lines) {
|
|
218
|
+
const legacy = new Set(LEGACY_PATTERNS);
|
|
219
|
+
const kept = [];
|
|
220
|
+
const removed = [];
|
|
221
|
+
for (const ln of lines) {
|
|
222
|
+
const s = _strip(ln).replace(/^\s+/, "");
|
|
223
|
+
if (legacy.has(s) || s.startsWith("/") && legacy.has(s.slice(1))) {
|
|
224
|
+
removed.push(s);
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
kept.push(ln);
|
|
228
|
+
}
|
|
229
|
+
return [kept, removed];
|
|
230
|
+
}
|
|
231
|
+
function format_file(lines) {
|
|
232
|
+
const text = lines.join("\n");
|
|
233
|
+
return text.replace(/\n+$/, "") + "\n";
|
|
234
|
+
}
|
|
235
|
+
function render_diff(old_text, new_text, p) {
|
|
236
|
+
return unified_diff(
|
|
237
|
+
_splitlinesKeepends(old_text),
|
|
238
|
+
_splitlinesKeepends(new_text),
|
|
239
|
+
p,
|
|
240
|
+
p,
|
|
241
|
+
3
|
|
242
|
+
).join("");
|
|
243
|
+
}
|
|
244
|
+
function _splitlinesKeepends(text) {
|
|
245
|
+
if (text === "") return [];
|
|
246
|
+
const out = [];
|
|
247
|
+
let buf = "";
|
|
248
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
249
|
+
const ch = text[i];
|
|
250
|
+
buf += ch;
|
|
251
|
+
if (ch === "\n") {
|
|
252
|
+
out.push(buf);
|
|
253
|
+
buf = "";
|
|
254
|
+
} else if (ch === "\r") {
|
|
255
|
+
if (text[i + 1] === "\n") {
|
|
256
|
+
buf += "\n";
|
|
257
|
+
i += 1;
|
|
258
|
+
}
|
|
259
|
+
out.push(buf);
|
|
260
|
+
buf = "";
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (buf !== "") out.push(buf);
|
|
264
|
+
return out;
|
|
265
|
+
}
|
|
266
|
+
function _matchingBlocks(a, b) {
|
|
267
|
+
const b2j = /* @__PURE__ */ new Map();
|
|
268
|
+
for (let i = 0; i < b.length; i += 1) {
|
|
269
|
+
const el = b[i];
|
|
270
|
+
const arr = b2j.get(el);
|
|
271
|
+
if (arr) arr.push(i);
|
|
272
|
+
else b2j.set(el, [i]);
|
|
273
|
+
}
|
|
274
|
+
function findLongest(alo, ahi, blo, bhi) {
|
|
275
|
+
let besti = alo;
|
|
276
|
+
let bestj = blo;
|
|
277
|
+
let bestsize = 0;
|
|
278
|
+
let j2len = /* @__PURE__ */ new Map();
|
|
279
|
+
for (let i = alo; i < ahi; i += 1) {
|
|
280
|
+
const newj2len = /* @__PURE__ */ new Map();
|
|
281
|
+
const js = b2j.get(a[i]) ?? [];
|
|
282
|
+
for (const j of js) {
|
|
283
|
+
if (j < blo) continue;
|
|
284
|
+
if (j >= bhi) break;
|
|
285
|
+
const k = (j2len.get(j - 1) ?? 0) + 1;
|
|
286
|
+
newj2len.set(j, k);
|
|
287
|
+
if (k > bestsize) {
|
|
288
|
+
besti = i - k + 1;
|
|
289
|
+
bestj = j - k + 1;
|
|
290
|
+
bestsize = k;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
j2len = newj2len;
|
|
294
|
+
}
|
|
295
|
+
return [besti, bestj, bestsize];
|
|
296
|
+
}
|
|
297
|
+
const queue = [[0, a.length, 0, b.length]];
|
|
298
|
+
const blocks = [];
|
|
299
|
+
while (queue.length > 0) {
|
|
300
|
+
const [alo, ahi, blo, bhi] = queue.pop();
|
|
301
|
+
const [i, j, k] = findLongest(alo, ahi, blo, bhi);
|
|
302
|
+
if (k > 0) {
|
|
303
|
+
blocks.push([i, j, k]);
|
|
304
|
+
if (alo < i && blo < j) queue.push([alo, i, blo, j]);
|
|
305
|
+
if (i + k < ahi && j + k < bhi) queue.push([i + k, ahi, j + k, bhi]);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
blocks.sort((x, y) => x[0] - y[0] || x[1] - y[1]);
|
|
309
|
+
blocks.push([a.length, b.length, 0]);
|
|
310
|
+
return blocks;
|
|
311
|
+
}
|
|
312
|
+
function _getOpcodes(a, b) {
|
|
313
|
+
let i = 0;
|
|
314
|
+
let j = 0;
|
|
315
|
+
const answer = [];
|
|
316
|
+
for (const [ai, bj, size] of _matchingBlocks(a, b)) {
|
|
317
|
+
let tag = "";
|
|
318
|
+
if (i < ai && j < bj) tag = "replace";
|
|
319
|
+
else if (i < ai) tag = "delete";
|
|
320
|
+
else if (j < bj) tag = "insert";
|
|
321
|
+
if (tag) answer.push({ tag, i1: i, i2: ai, j1: j, j2: bj });
|
|
322
|
+
i = ai + size;
|
|
323
|
+
j = bj + size;
|
|
324
|
+
if (size > 0) answer.push({ tag: "equal", i1: ai, i2: i, j1: bj, j2: j });
|
|
325
|
+
}
|
|
326
|
+
return answer;
|
|
327
|
+
}
|
|
328
|
+
function _getGroupedOpcodes(a, b, n) {
|
|
329
|
+
let codes = _getOpcodes(a, b);
|
|
330
|
+
if (codes.length === 0) {
|
|
331
|
+
codes = [{ tag: "equal", i1: 0, i2: 1, j1: 0, j2: 1 }];
|
|
332
|
+
}
|
|
333
|
+
if (codes[0].tag === "equal") {
|
|
334
|
+
const c = codes[0];
|
|
335
|
+
codes[0] = {
|
|
336
|
+
tag: c.tag,
|
|
337
|
+
i1: Math.max(c.i1, c.i2 - n),
|
|
338
|
+
i2: c.i2,
|
|
339
|
+
j1: Math.max(c.j1, c.j2 - n),
|
|
340
|
+
j2: c.j2
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
const last = codes[codes.length - 1];
|
|
344
|
+
if (last.tag === "equal") {
|
|
345
|
+
codes[codes.length - 1] = {
|
|
346
|
+
tag: last.tag,
|
|
347
|
+
i1: last.i1,
|
|
348
|
+
i2: Math.min(last.i2, last.i1 + n),
|
|
349
|
+
j1: last.j1,
|
|
350
|
+
j2: Math.min(last.j2, last.j1 + n)
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
const nn = n + n;
|
|
354
|
+
const groups = [];
|
|
355
|
+
let group = [];
|
|
356
|
+
for (const code of codes) {
|
|
357
|
+
let { i1, j1 } = code;
|
|
358
|
+
const { tag, i2, j2 } = code;
|
|
359
|
+
if (tag === "equal" && i2 - i1 > nn) {
|
|
360
|
+
group.push({ tag, i1, i2: Math.min(i2, i1 + n), j1, j2: Math.min(j2, j1 + n) });
|
|
361
|
+
groups.push(group);
|
|
362
|
+
group = [];
|
|
363
|
+
i1 = Math.max(i1, i2 - n);
|
|
364
|
+
j1 = Math.max(j1, j2 - n);
|
|
365
|
+
}
|
|
366
|
+
group.push({ tag, i1, i2, j1, j2 });
|
|
367
|
+
}
|
|
368
|
+
if (group.length > 0 && !(group.length === 1 && group[0].tag === "equal")) {
|
|
369
|
+
groups.push(group);
|
|
370
|
+
}
|
|
371
|
+
return groups;
|
|
372
|
+
}
|
|
373
|
+
function _formatRangeUnified(start, stop) {
|
|
374
|
+
let beginning = start + 1;
|
|
375
|
+
const length = stop - start;
|
|
376
|
+
if (length === 1) return `${beginning}`;
|
|
377
|
+
if (length === 0) beginning -= 1;
|
|
378
|
+
return `${beginning},${length}`;
|
|
379
|
+
}
|
|
380
|
+
function unified_diff(a, b, fromfile, tofile, n) {
|
|
381
|
+
const out = [];
|
|
382
|
+
let started = false;
|
|
383
|
+
for (const group of _getGroupedOpcodes(a, b, n)) {
|
|
384
|
+
if (!started) {
|
|
385
|
+
started = true;
|
|
386
|
+
out.push(`--- ${fromfile}
|
|
387
|
+
`);
|
|
388
|
+
out.push(`+++ ${tofile}
|
|
389
|
+
`);
|
|
390
|
+
}
|
|
391
|
+
const first = group[0];
|
|
392
|
+
const last = group[group.length - 1];
|
|
393
|
+
const file1Range = _formatRangeUnified(first.i1, last.i2);
|
|
394
|
+
const file2Range = _formatRangeUnified(first.j1, last.j2);
|
|
395
|
+
out.push(`@@ -${file1Range} +${file2Range} @@
|
|
396
|
+
`);
|
|
397
|
+
for (const { tag, i1, i2, j1, j2 } of group) {
|
|
398
|
+
if (tag === "equal") {
|
|
399
|
+
for (const line of a.slice(i1, i2)) out.push(" " + line);
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
if (tag === "replace" || tag === "delete") {
|
|
403
|
+
for (const line of a.slice(i1, i2)) out.push("-" + line);
|
|
404
|
+
}
|
|
405
|
+
if (tag === "replace" || tag === "insert") {
|
|
406
|
+
for (const line of b.slice(j1, j2)) out.push("+" + line);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
return out;
|
|
411
|
+
}
|
|
412
|
+
var _PROG = "sync_gitignore.py";
|
|
413
|
+
function _argError(usage, msg) {
|
|
414
|
+
process.stderr.write(usage);
|
|
415
|
+
process.stderr.write(`${_PROG}: error: ${msg}
|
|
416
|
+
`);
|
|
417
|
+
process.exit(2);
|
|
418
|
+
}
|
|
419
|
+
function parse_args(argv) {
|
|
420
|
+
const args = {
|
|
421
|
+
path: DEFAULT_GITIGNORE,
|
|
422
|
+
template: DEFAULT_TEMPLATE,
|
|
423
|
+
dry_run: false,
|
|
424
|
+
replace: false,
|
|
425
|
+
cleanup_legacy: false,
|
|
426
|
+
quiet: false
|
|
427
|
+
};
|
|
428
|
+
const usage = "usage: sync_gitignore.py [-h] [--path PATH] [--template TEMPLATE]\n [--dry-run] [--replace] [--cleanup-legacy]\n [--quiet]\n";
|
|
429
|
+
const valueFlags = {
|
|
430
|
+
"--path": "path",
|
|
431
|
+
"--template": "template"
|
|
432
|
+
};
|
|
433
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
434
|
+
const arg = argv[i];
|
|
435
|
+
if (arg === "-h" || arg === "--help") {
|
|
436
|
+
process.stdout.write(usage);
|
|
437
|
+
process.exit(0);
|
|
438
|
+
} else if (arg === "--dry-run") {
|
|
439
|
+
args.dry_run = true;
|
|
440
|
+
} else if (arg === "--replace") {
|
|
441
|
+
args.replace = true;
|
|
442
|
+
} else if (arg === "--cleanup-legacy") {
|
|
443
|
+
args.cleanup_legacy = true;
|
|
444
|
+
} else if (arg === "--quiet") {
|
|
445
|
+
args.quiet = true;
|
|
446
|
+
} else if (valueFlags[arg] !== void 0) {
|
|
447
|
+
const next = argv[i + 1];
|
|
448
|
+
if (next === void 0) {
|
|
449
|
+
_argError(usage, `argument ${arg}: expected one argument`);
|
|
450
|
+
}
|
|
451
|
+
args[valueFlags[arg]] = next;
|
|
452
|
+
i += 1;
|
|
453
|
+
} else {
|
|
454
|
+
const eq = arg.indexOf("=");
|
|
455
|
+
const flag = eq === -1 ? arg : arg.slice(0, eq);
|
|
456
|
+
if (eq !== -1 && valueFlags[flag] !== void 0) {
|
|
457
|
+
args[valueFlags[flag]] = arg.slice(eq + 1);
|
|
458
|
+
} else {
|
|
459
|
+
_argError(usage, `unrecognized arguments: ${arg}`);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return args;
|
|
464
|
+
}
|
|
465
|
+
function main(argv) {
|
|
466
|
+
const args = parse_args(argv);
|
|
467
|
+
let template_lines;
|
|
468
|
+
try {
|
|
469
|
+
template_lines = load_template(args.template);
|
|
470
|
+
} catch (exc) {
|
|
471
|
+
if (exc instanceof TemplateNotFoundError) {
|
|
472
|
+
process.stderr.write(`error: ${exc.message}
|
|
473
|
+
`);
|
|
474
|
+
return 2;
|
|
475
|
+
}
|
|
476
|
+
throw exc;
|
|
477
|
+
}
|
|
478
|
+
const target = args.path;
|
|
479
|
+
let existing_text;
|
|
480
|
+
let existing_lines;
|
|
481
|
+
if (_isFile(target)) {
|
|
482
|
+
existing_text = fs2.readFileSync(target, "utf-8");
|
|
483
|
+
existing_lines = _splitlines(existing_text).map(_strip);
|
|
484
|
+
} else {
|
|
485
|
+
existing_text = "";
|
|
486
|
+
existing_lines = [];
|
|
487
|
+
}
|
|
488
|
+
let removed_legacy = [];
|
|
489
|
+
if (args.cleanup_legacy) {
|
|
490
|
+
[existing_lines, removed_legacy] = cleanup_legacy(existing_lines);
|
|
491
|
+
}
|
|
492
|
+
const [new_lines, added] = sync_block(existing_lines, template_lines, { replace: args.replace });
|
|
493
|
+
const new_text = format_file(new_lines);
|
|
494
|
+
if (new_text === existing_text) {
|
|
495
|
+
if (!args.quiet) {
|
|
496
|
+
process.stdout.write(
|
|
497
|
+
`\u2705 ${target}: block already in sync (${template_entries(template_lines).length} entries)
|
|
498
|
+
`
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
return 0;
|
|
502
|
+
}
|
|
503
|
+
if (args.dry_run) {
|
|
504
|
+
const diff = render_diff(existing_text, new_text, target);
|
|
505
|
+
process.stdout.write(diff);
|
|
506
|
+
if (!args.quiet) {
|
|
507
|
+
process.stderr.write(
|
|
508
|
+
`
|
|
509
|
+
(dry-run) would add ${added.length} entr${added.length === 1 ? "y" : "ies"} to ${target}
|
|
510
|
+
`
|
|
511
|
+
);
|
|
512
|
+
if (removed_legacy.length > 0) {
|
|
513
|
+
process.stderr.write(
|
|
514
|
+
`(dry-run) would remove ${removed_legacy.length} legacy entr${removed_legacy.length === 1 ? "y" : "ies"}: ${removed_legacy.join(", ")}
|
|
515
|
+
`
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
return 0;
|
|
520
|
+
}
|
|
521
|
+
fs2.mkdirSync(path2.dirname(path2.resolve(target)), { recursive: true });
|
|
522
|
+
fs2.writeFileSync(target, new_text, "utf-8");
|
|
523
|
+
if (!args.quiet) {
|
|
524
|
+
const action = args.replace ? "replaced" : "updated";
|
|
525
|
+
process.stdout.write(
|
|
526
|
+
`\u2705 ${target}: ${action} block (${added.length} entr${added.length === 1 ? "y" : "ies"} added)
|
|
527
|
+
`
|
|
528
|
+
);
|
|
529
|
+
if (removed_legacy.length > 0) {
|
|
530
|
+
process.stdout.write(
|
|
531
|
+
` removed ${removed_legacy.length} legacy entr${removed_legacy.length === 1 ? "y" : "ies"}: ${removed_legacy.join(", ")}
|
|
532
|
+
`
|
|
533
|
+
);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
return 0;
|
|
537
|
+
}
|
|
538
|
+
function _isCliEntry() {
|
|
539
|
+
if (process.argv[1] === void 0) {
|
|
540
|
+
return false;
|
|
541
|
+
}
|
|
542
|
+
const argvUrl = pathToFileURL(path2.resolve(process.argv[1])).href;
|
|
543
|
+
if (import.meta.url === argvUrl) {
|
|
544
|
+
return true;
|
|
545
|
+
}
|
|
546
|
+
try {
|
|
547
|
+
const here = fs2.realpathSync(fileURLToPath2(import.meta.url));
|
|
548
|
+
const argv = fs2.realpathSync(path2.resolve(process.argv[1]));
|
|
549
|
+
return here === argv;
|
|
550
|
+
} catch {
|
|
551
|
+
return false;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
if (_isCliEntry() || process.argv[1] === _HERE) {
|
|
555
|
+
process.exit(main(process.argv.slice(2)));
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
// src/scripts/sync_gitattributes.ts
|
|
559
|
+
var sync_gitattributes_exports = {};
|
|
560
|
+
__export(sync_gitattributes_exports, {
|
|
561
|
+
DEFAULT_GITATTRIBUTES: () => DEFAULT_GITATTRIBUTES,
|
|
562
|
+
DEFAULT_TEMPLATE: () => DEFAULT_TEMPLATE2,
|
|
563
|
+
SECTION_FOOTER: () => SECTION_FOOTER2,
|
|
564
|
+
SECTION_HEADER: () => SECTION_HEADER2,
|
|
565
|
+
TemplateNotFoundError: () => TemplateNotFoundError2,
|
|
566
|
+
block_entries: () => block_entries2,
|
|
567
|
+
build_fresh_block: () => build_fresh_block2,
|
|
568
|
+
find_block: () => find_block2,
|
|
569
|
+
format_file: () => format_file2,
|
|
570
|
+
load_template: () => load_template2,
|
|
571
|
+
main: () => main2,
|
|
572
|
+
sync_block: () => sync_block2,
|
|
573
|
+
template_entries: () => template_entries2
|
|
574
|
+
});
|
|
575
|
+
import * as fs3 from "node:fs";
|
|
576
|
+
import * as path3 from "node:path";
|
|
577
|
+
import process2 from "node:process";
|
|
578
|
+
import { fileURLToPath as fileURLToPath3, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
579
|
+
var SECTION_HEADER2 = "# --- BEGIN agent-config managed: memory merge attributes ---";
|
|
580
|
+
var SECTION_FOOTER2 = "# --- END agent-config managed: memory merge attributes ---";
|
|
581
|
+
var DEFAULT_GITATTRIBUTES = ".gitattributes";
|
|
582
|
+
var _HERE2 = fileURLToPath3(import.meta.url);
|
|
583
|
+
var DEFAULT_TEMPLATE2 = path3.join(
|
|
584
|
+
path3.dirname(_HERE2),
|
|
585
|
+
"..",
|
|
586
|
+
"agent-src",
|
|
587
|
+
"templates",
|
|
588
|
+
"agents",
|
|
589
|
+
".gitattributes.fragment"
|
|
590
|
+
);
|
|
591
|
+
function _strip2(ln) {
|
|
592
|
+
return ln.replace(/\n+$/, "").replace(/\s+$/, "");
|
|
593
|
+
}
|
|
594
|
+
function _is_entry2(ln) {
|
|
595
|
+
const s = _strip2(ln).replace(/^\s+/, "");
|
|
596
|
+
return Boolean(s) && !s.startsWith("#");
|
|
597
|
+
}
|
|
598
|
+
var TemplateNotFoundError2 = class extends Error {
|
|
599
|
+
constructor(p) {
|
|
600
|
+
super(`template not found: ${p}`);
|
|
601
|
+
this.name = "TemplateNotFoundError";
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
function _isFile2(p) {
|
|
605
|
+
try {
|
|
606
|
+
return fs3.statSync(p).isFile();
|
|
607
|
+
} catch {
|
|
608
|
+
return false;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
function _splitlines2(text) {
|
|
612
|
+
if (text === "") return [];
|
|
613
|
+
const parts = text.split(/\r\n|\r|\n/);
|
|
614
|
+
if (parts.length > 0 && parts[parts.length - 1] === "") parts.pop();
|
|
615
|
+
return parts;
|
|
616
|
+
}
|
|
617
|
+
function load_template2(p) {
|
|
618
|
+
if (!_isFile2(p)) {
|
|
619
|
+
throw new TemplateNotFoundError2(p);
|
|
620
|
+
}
|
|
621
|
+
const text = fs3.readFileSync(p, "utf-8");
|
|
622
|
+
return _splitlines2(text).map(_strip2);
|
|
623
|
+
}
|
|
624
|
+
function find_block2(lines) {
|
|
625
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
626
|
+
if (_strip2(lines[i]) === SECTION_HEADER2) {
|
|
627
|
+
for (let j = i + 1; j < lines.length; j += 1) {
|
|
628
|
+
if (_strip2(lines[j]) === SECTION_FOOTER2) {
|
|
629
|
+
return [i, j + 1];
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
return [i, lines.length];
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
return null;
|
|
636
|
+
}
|
|
637
|
+
function block_entries2(block_lines) {
|
|
638
|
+
return block_lines.filter((ln) => _is_entry2(ln)).map((ln) => _strip2(ln).replace(/^\s+/, ""));
|
|
639
|
+
}
|
|
640
|
+
function template_entries2(template_lines) {
|
|
641
|
+
return template_lines.filter((ln) => _is_entry2(ln)).map((ln) => ln.replace(/^\s+/, ""));
|
|
642
|
+
}
|
|
643
|
+
function build_fresh_block2(template_lines) {
|
|
644
|
+
return [SECTION_HEADER2, ...template_lines, SECTION_FOOTER2];
|
|
645
|
+
}
|
|
646
|
+
function sync_block2(existing_lines, template_lines) {
|
|
647
|
+
const loc = find_block2(existing_lines);
|
|
648
|
+
const fresh = build_fresh_block2(template_lines);
|
|
649
|
+
if (loc === null) {
|
|
650
|
+
const newLines = [...existing_lines];
|
|
651
|
+
if (newLines.length > 0 && _strip2(newLines[newLines.length - 1]) !== "") {
|
|
652
|
+
newLines.push("");
|
|
653
|
+
}
|
|
654
|
+
newLines.push(...fresh);
|
|
655
|
+
return [newLines, template_entries2(template_lines)];
|
|
656
|
+
}
|
|
657
|
+
const [start, end] = loc;
|
|
658
|
+
const head = existing_lines.slice(0, start);
|
|
659
|
+
let block = existing_lines.slice(start, end);
|
|
660
|
+
const tail = existing_lines.slice(end);
|
|
661
|
+
const existing_entries = new Set(block_entries2(block));
|
|
662
|
+
const missing = template_entries2(template_lines).filter((e) => !existing_entries.has(e));
|
|
663
|
+
if (missing.length === 0) {
|
|
664
|
+
return [[...existing_lines], []];
|
|
665
|
+
}
|
|
666
|
+
let insert_at;
|
|
667
|
+
if (block.length > 0 && _strip2(block[block.length - 1]) === SECTION_FOOTER2) {
|
|
668
|
+
insert_at = block.length - 1;
|
|
669
|
+
} else {
|
|
670
|
+
block = [...block, SECTION_FOOTER2];
|
|
671
|
+
insert_at = block.length - 1;
|
|
672
|
+
}
|
|
673
|
+
const new_block = [...block.slice(0, insert_at), ...missing, ...block.slice(insert_at)];
|
|
674
|
+
return [[...head, ...new_block, ...tail], missing];
|
|
675
|
+
}
|
|
676
|
+
function format_file2(lines) {
|
|
677
|
+
const text = lines.join("\n");
|
|
678
|
+
return text.replace(/\n+$/, "") + "\n";
|
|
679
|
+
}
|
|
680
|
+
var _PROG2 = "sync_gitattributes";
|
|
681
|
+
function _argError2(usage, msg) {
|
|
682
|
+
process2.stderr.write(usage);
|
|
683
|
+
process2.stderr.write(`${_PROG2}: error: ${msg}
|
|
684
|
+
`);
|
|
685
|
+
process2.exit(2);
|
|
686
|
+
}
|
|
687
|
+
function parse_args2(argv) {
|
|
688
|
+
const args = {
|
|
689
|
+
path: DEFAULT_GITATTRIBUTES,
|
|
690
|
+
template: DEFAULT_TEMPLATE2,
|
|
691
|
+
check: false,
|
|
692
|
+
quiet: false
|
|
693
|
+
};
|
|
694
|
+
const usage = "usage: sync_gitattributes [-h] [--path PATH] [--template TEMPLATE] [--check] [--quiet]\n";
|
|
695
|
+
const valueFlags = {
|
|
696
|
+
"--path": "path",
|
|
697
|
+
"--template": "template"
|
|
698
|
+
};
|
|
699
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
700
|
+
const arg = argv[i];
|
|
701
|
+
if (arg === "-h" || arg === "--help") {
|
|
702
|
+
process2.stdout.write(usage);
|
|
703
|
+
process2.exit(0);
|
|
704
|
+
} else if (arg === "--check") {
|
|
705
|
+
args.check = true;
|
|
706
|
+
} else if (arg === "--quiet") {
|
|
707
|
+
args.quiet = true;
|
|
708
|
+
} else if (valueFlags[arg] !== void 0) {
|
|
709
|
+
const next = argv[i + 1];
|
|
710
|
+
if (next === void 0) {
|
|
711
|
+
_argError2(usage, `argument ${arg}: expected one argument`);
|
|
712
|
+
}
|
|
713
|
+
args[valueFlags[arg]] = next;
|
|
714
|
+
i += 1;
|
|
715
|
+
} else {
|
|
716
|
+
const eq = arg.indexOf("=");
|
|
717
|
+
const flag = eq === -1 ? arg : arg.slice(0, eq);
|
|
718
|
+
if (eq !== -1 && valueFlags[flag] !== void 0) {
|
|
719
|
+
args[valueFlags[flag]] = arg.slice(eq + 1);
|
|
720
|
+
} else {
|
|
721
|
+
_argError2(usage, `unrecognized arguments: ${arg}`);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
return args;
|
|
726
|
+
}
|
|
727
|
+
function main2(argv) {
|
|
728
|
+
const args = parse_args2(argv);
|
|
729
|
+
let template_lines;
|
|
730
|
+
try {
|
|
731
|
+
template_lines = load_template2(args.template);
|
|
732
|
+
} catch (exc) {
|
|
733
|
+
if (exc instanceof TemplateNotFoundError2) {
|
|
734
|
+
process2.stderr.write(`error: ${exc.message}
|
|
735
|
+
`);
|
|
736
|
+
return 2;
|
|
737
|
+
}
|
|
738
|
+
throw exc;
|
|
739
|
+
}
|
|
740
|
+
const target = args.path;
|
|
741
|
+
let existing_text;
|
|
742
|
+
let existing_lines;
|
|
743
|
+
if (_isFile2(target)) {
|
|
744
|
+
existing_text = fs3.readFileSync(target, "utf-8");
|
|
745
|
+
existing_lines = _splitlines2(existing_text).map(_strip2);
|
|
746
|
+
} else {
|
|
747
|
+
existing_text = "";
|
|
748
|
+
existing_lines = [];
|
|
749
|
+
}
|
|
750
|
+
const [new_lines, added] = sync_block2(existing_lines, template_lines);
|
|
751
|
+
const new_text = format_file2(new_lines);
|
|
752
|
+
if (new_text === existing_text) {
|
|
753
|
+
if (!args.quiet) {
|
|
754
|
+
process2.stdout.write(
|
|
755
|
+
`\u2705 ${target}: block already in sync (${template_entries2(template_lines).length} entries)
|
|
756
|
+
`
|
|
757
|
+
);
|
|
758
|
+
}
|
|
759
|
+
return 0;
|
|
760
|
+
}
|
|
761
|
+
if (args.check) {
|
|
762
|
+
if (!args.quiet) {
|
|
763
|
+
process2.stderr.write(
|
|
764
|
+
`\u26A0\uFE0F ${target}: missing ${added.length} managed entr${added.length === 1 ? "y" : "ies"} \u2014 run without --check to apply
|
|
765
|
+
`
|
|
766
|
+
);
|
|
767
|
+
}
|
|
768
|
+
return 1;
|
|
769
|
+
}
|
|
770
|
+
fs3.mkdirSync(path3.dirname(path3.resolve(target)), { recursive: true });
|
|
771
|
+
fs3.writeFileSync(target, new_text, "utf-8");
|
|
772
|
+
if (!args.quiet) {
|
|
773
|
+
process2.stdout.write(
|
|
774
|
+
`\u2705 ${target}: updated block (${added.length} entr${added.length === 1 ? "y" : "ies"} added)
|
|
775
|
+
`
|
|
776
|
+
);
|
|
777
|
+
}
|
|
778
|
+
return 0;
|
|
779
|
+
}
|
|
780
|
+
function _isCliEntry2() {
|
|
781
|
+
if (process2.argv[1] === void 0) {
|
|
782
|
+
return false;
|
|
783
|
+
}
|
|
784
|
+
const argvUrl = pathToFileURL2(path3.resolve(process2.argv[1])).href;
|
|
785
|
+
if (import.meta.url === argvUrl) {
|
|
786
|
+
return true;
|
|
787
|
+
}
|
|
788
|
+
try {
|
|
789
|
+
const here = fs3.realpathSync(fileURLToPath3(import.meta.url));
|
|
790
|
+
const argv = fs3.realpathSync(path3.resolve(process2.argv[1]));
|
|
791
|
+
return here === argv;
|
|
792
|
+
} catch {
|
|
793
|
+
return false;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
if (_isCliEntry2() || process2.argv[1] === _HERE2) {
|
|
797
|
+
process2.exit(main2(process2.argv.slice(2)));
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
// src/scripts/_cli/cmd_refresh.ts
|
|
801
|
+
var PACKAGE_ROOT = resolvePackageRoot(import.meta.url);
|
|
802
|
+
var _HERE3 = fileURLToPath4(import.meta.url);
|
|
803
|
+
var ArgparseExit = class extends Error {
|
|
804
|
+
constructor(code) {
|
|
805
|
+
super(`argparse-exit-${code}`);
|
|
806
|
+
this.code = code;
|
|
807
|
+
}
|
|
808
|
+
code;
|
|
809
|
+
};
|
|
810
|
+
var _stdout = { write: (t) => process3.stdout.write(t) };
|
|
811
|
+
var _stderr = { write: (t) => process3.stderr.write(t) };
|
|
812
|
+
function _print(out, line = "") {
|
|
813
|
+
out.write(line + "\n");
|
|
814
|
+
}
|
|
815
|
+
function _isFile3(p) {
|
|
816
|
+
try {
|
|
817
|
+
return fs4.statSync(p).isFile();
|
|
818
|
+
} catch {
|
|
819
|
+
return false;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
function _isDir(p) {
|
|
823
|
+
try {
|
|
824
|
+
return fs4.statSync(p).isDirectory();
|
|
825
|
+
} catch {
|
|
826
|
+
return false;
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
function _exists(p) {
|
|
830
|
+
try {
|
|
831
|
+
fs4.statSync(p);
|
|
832
|
+
return true;
|
|
833
|
+
} catch {
|
|
834
|
+
return false;
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
function _readText(p) {
|
|
838
|
+
return fs4.readFileSync(p, { encoding: "utf-8" });
|
|
839
|
+
}
|
|
840
|
+
function _writeText(p, text) {
|
|
841
|
+
fs4.writeFileSync(p, text, { encoding: "utf-8" });
|
|
842
|
+
}
|
|
843
|
+
var CONSUMER_BRIDGE_MARKER_RELPATH = path4.join("agents", ".event4u-bridge.yml");
|
|
844
|
+
var SRC_MARKER_DIR = ".agent-src.uncondensed";
|
|
845
|
+
function _remove_legacy_consumer_bridge_marker(project_root, env = null) {
|
|
846
|
+
const env_map = env ?? process3.env;
|
|
847
|
+
if (env_map["AGENT_CONFIG_DEV_MODE"] === "1") return null;
|
|
848
|
+
if (_isDir(path4.join(project_root, SRC_MARKER_DIR))) return null;
|
|
849
|
+
const target = path4.join(project_root, CONSUMER_BRIDGE_MARKER_RELPATH);
|
|
850
|
+
if (!_isFile3(target)) return null;
|
|
851
|
+
try {
|
|
852
|
+
fs4.rmSync(target);
|
|
853
|
+
} catch {
|
|
854
|
+
return null;
|
|
855
|
+
}
|
|
856
|
+
return target;
|
|
857
|
+
}
|
|
858
|
+
function _default_runner(cmd) {
|
|
859
|
+
const r = spawnSync(cmd[0], cmd.slice(1), { stdio: "inherit" });
|
|
860
|
+
if (r.error) {
|
|
861
|
+
_stderr.write(`agent-config refresh: cannot run ${cmd[0]}: ${osErrorStr(r.error)}
|
|
862
|
+
`);
|
|
863
|
+
return 1;
|
|
864
|
+
}
|
|
865
|
+
return r.status ?? 1;
|
|
866
|
+
}
|
|
867
|
+
function osErrorStr(exc) {
|
|
868
|
+
if (exc && typeof exc === "object" && "message" in exc) {
|
|
869
|
+
return String(exc.message);
|
|
870
|
+
}
|
|
871
|
+
return String(exc);
|
|
872
|
+
}
|
|
873
|
+
function _refresh_global(runner, out, err) {
|
|
874
|
+
const install_sh = path4.join(PACKAGE_ROOT, "src", "scripts", "install");
|
|
875
|
+
if (!_isFile3(install_sh)) {
|
|
876
|
+
_print(err, `\u274C agent-config refresh: installer not found at ${install_sh}`);
|
|
877
|
+
return 1;
|
|
878
|
+
}
|
|
879
|
+
_print(out, "\u2192 refreshing global install (scripts/install --global)");
|
|
880
|
+
const rc = runner(["bash", install_sh, "--global"]);
|
|
881
|
+
if (rc !== 0) {
|
|
882
|
+
_print(err, `\u274C agent-config refresh --global: install failed (exit ${rc})`);
|
|
883
|
+
return 1;
|
|
884
|
+
}
|
|
885
|
+
_print(out, "\u2705 global install refreshed.");
|
|
886
|
+
return 0;
|
|
887
|
+
}
|
|
888
|
+
function _is_source_repo(project_root) {
|
|
889
|
+
if (_isDir(path4.join(project_root, "dist/agent-src"))) {
|
|
890
|
+
return true;
|
|
891
|
+
}
|
|
892
|
+
if (_glob_packages_uncondensed(project_root).length > 0) {
|
|
893
|
+
return true;
|
|
894
|
+
}
|
|
895
|
+
const pkg = path4.join(project_root, "package.json");
|
|
896
|
+
if (_isFile3(pkg)) {
|
|
897
|
+
try {
|
|
898
|
+
const data = JSON.parse(_readText(pkg));
|
|
899
|
+
if (data["name"] === "@event4u/agent-config") {
|
|
900
|
+
return true;
|
|
901
|
+
}
|
|
902
|
+
} catch {
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
return false;
|
|
906
|
+
}
|
|
907
|
+
function _glob_packages_uncondensed(project_root) {
|
|
908
|
+
const packages = path4.join(project_root, "packages");
|
|
909
|
+
let entries;
|
|
910
|
+
try {
|
|
911
|
+
entries = fs4.readdirSync(packages);
|
|
912
|
+
} catch {
|
|
913
|
+
return [];
|
|
914
|
+
}
|
|
915
|
+
const out = [];
|
|
916
|
+
for (const name of entries) {
|
|
917
|
+
const candidate = path4.join(packages, name, SRC_MARKER_DIR);
|
|
918
|
+
if (_exists(candidate)) {
|
|
919
|
+
out.push(candidate);
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
return out;
|
|
923
|
+
}
|
|
924
|
+
function _refresh_project(project_root, out, err) {
|
|
925
|
+
if (_is_source_repo(project_root)) {
|
|
926
|
+
_print(
|
|
927
|
+
out,
|
|
928
|
+
"\u2139\uFE0F refresh --project skipped: this is the agent-config package itself (or a checkout of it). Maintainers use AGENT_CONFIG_DEV_MODE=1, not a consumer refresh."
|
|
929
|
+
);
|
|
930
|
+
return 0;
|
|
931
|
+
}
|
|
932
|
+
const removed = _remove_legacy_consumer_bridge_marker(project_root);
|
|
933
|
+
if (removed !== null) {
|
|
934
|
+
_print(out, `\u2705 removed legacy bridge marker: ${removed}`);
|
|
935
|
+
}
|
|
936
|
+
const overrides = path4.join(project_root, "agents", "overrides");
|
|
937
|
+
fs4.mkdirSync(overrides, { recursive: true });
|
|
938
|
+
const keep = path4.join(overrides, "README.md");
|
|
939
|
+
if (!_exists(keep)) {
|
|
940
|
+
_writeText(
|
|
941
|
+
keep,
|
|
942
|
+
"# Project overrides\n\nProject-local overrides/extensions of shared skills, rules, and commands. The only project-side agent surface ADR-020 permits. See the `override-management` skill.\n"
|
|
943
|
+
);
|
|
944
|
+
}
|
|
945
|
+
_print(out, `\u2705 overrides scaffold: ${overrides}`);
|
|
946
|
+
const wrapper = install_cli_wrapper(project_root);
|
|
947
|
+
if (wrapper !== null) {
|
|
948
|
+
_print(out, `\u2705 ./agent-config wrapper refreshed: ${wrapper}`);
|
|
949
|
+
}
|
|
950
|
+
const rc = _sync_gitignore(project_root, out, err);
|
|
951
|
+
if (rc !== 0) {
|
|
952
|
+
return rc;
|
|
953
|
+
}
|
|
954
|
+
_sync_gitattributes(project_root, out, err);
|
|
955
|
+
_print(out, "\u2705 refresh --project complete.");
|
|
956
|
+
return 0;
|
|
957
|
+
}
|
|
958
|
+
function _sync_gitignore(project_root, out, err) {
|
|
959
|
+
let mod;
|
|
960
|
+
try {
|
|
961
|
+
mod = sync_gitignore_exports;
|
|
962
|
+
} catch (exc) {
|
|
963
|
+
_print(err, `\u26A0\uFE0F refresh --project: gitignore sync unavailable (${osErrorStr(exc)})`);
|
|
964
|
+
return 0;
|
|
965
|
+
}
|
|
966
|
+
const rc = mod.main(["--path", path4.join(project_root, ".gitignore")]);
|
|
967
|
+
if (rc !== 0 && rc !== null && rc !== void 0) {
|
|
968
|
+
_print(err, `\u26A0\uFE0F refresh --project: gitignore sync returned ${rc}`);
|
|
969
|
+
} else {
|
|
970
|
+
_print(out, "\u2705 .gitignore agents/ block synced.");
|
|
971
|
+
}
|
|
972
|
+
return 0;
|
|
973
|
+
}
|
|
974
|
+
function _sync_gitattributes(project_root, out, err) {
|
|
975
|
+
let mod;
|
|
976
|
+
try {
|
|
977
|
+
mod = sync_gitattributes_exports;
|
|
978
|
+
} catch (exc) {
|
|
979
|
+
_print(err, `\u26A0\uFE0F refresh --project: gitattributes sync unavailable (${osErrorStr(exc)})`);
|
|
980
|
+
return 0;
|
|
981
|
+
}
|
|
982
|
+
const rc = mod.main(["--path", path4.join(project_root, ".gitattributes")]);
|
|
983
|
+
if (rc !== 0 && rc !== null && rc !== void 0) {
|
|
984
|
+
_print(err, `\u26A0\uFE0F refresh --project: gitattributes sync returned ${rc}`);
|
|
985
|
+
} else {
|
|
986
|
+
_print(out, "\u2705 .gitattributes memory merge-safety block synced.");
|
|
987
|
+
}
|
|
988
|
+
return 0;
|
|
989
|
+
}
|
|
990
|
+
var PROG = "agent-config refresh";
|
|
991
|
+
var USAGE = `usage: ${PROG} [-h] [--global] [--project]
|
|
992
|
+
`;
|
|
993
|
+
function _argError3(msg) {
|
|
994
|
+
_stderr.write(USAGE);
|
|
995
|
+
_stderr.write(`${PROG}: error: ${msg}
|
|
996
|
+
`);
|
|
997
|
+
throw new ArgparseExit(2);
|
|
998
|
+
}
|
|
999
|
+
function _parse(argv) {
|
|
1000
|
+
const args = { is_global: false, is_project: false };
|
|
1001
|
+
const positionals = [];
|
|
1002
|
+
let i = 0;
|
|
1003
|
+
while (i < argv.length) {
|
|
1004
|
+
const a = argv[i];
|
|
1005
|
+
if (a === "-h" || a === "--help") {
|
|
1006
|
+
_stdout.write(USAGE);
|
|
1007
|
+
throw new ArgparseExit(0);
|
|
1008
|
+
}
|
|
1009
|
+
const eq = a.startsWith("--") ? a.indexOf("=") : -1;
|
|
1010
|
+
const flag = eq >= 0 ? a.slice(0, eq) : a;
|
|
1011
|
+
const inlineVal = eq >= 0 ? a.slice(eq + 1) : null;
|
|
1012
|
+
if (flag === "--global") {
|
|
1013
|
+
if (inlineVal !== null) {
|
|
1014
|
+
_argError3(`argument --global: ignored explicit argument '${inlineVal}'`);
|
|
1015
|
+
}
|
|
1016
|
+
args.is_global = true;
|
|
1017
|
+
i += 1;
|
|
1018
|
+
continue;
|
|
1019
|
+
}
|
|
1020
|
+
if (flag === "--project") {
|
|
1021
|
+
if (inlineVal !== null) {
|
|
1022
|
+
_argError3(`argument --project: ignored explicit argument '${inlineVal}'`);
|
|
1023
|
+
}
|
|
1024
|
+
args.is_project = true;
|
|
1025
|
+
i += 1;
|
|
1026
|
+
continue;
|
|
1027
|
+
}
|
|
1028
|
+
if (a.startsWith("-") && a !== "-") {
|
|
1029
|
+
_argError3(`unrecognized arguments: ${a}`);
|
|
1030
|
+
}
|
|
1031
|
+
positionals.push(a);
|
|
1032
|
+
i += 1;
|
|
1033
|
+
}
|
|
1034
|
+
if (positionals.length > 0) {
|
|
1035
|
+
_argError3(`unrecognized arguments: ${positionals.join(" ")}`);
|
|
1036
|
+
}
|
|
1037
|
+
return args;
|
|
1038
|
+
}
|
|
1039
|
+
function main3(argv = null, options = {}) {
|
|
1040
|
+
const runner = options.runner ?? _default_runner;
|
|
1041
|
+
const out = options.out ?? _stdout;
|
|
1042
|
+
const err = options.err ?? _stderr;
|
|
1043
|
+
const args = _parse(argv ?? process3.argv.slice(2));
|
|
1044
|
+
if (!args.is_global && !args.is_project) {
|
|
1045
|
+
_print(
|
|
1046
|
+
err,
|
|
1047
|
+
"\u274C agent-config refresh: specify a scope \u2014 --global and/or --project (never a silent default)."
|
|
1048
|
+
);
|
|
1049
|
+
return 1;
|
|
1050
|
+
}
|
|
1051
|
+
const root = options.project_root ?? process3.cwd();
|
|
1052
|
+
let rc = 0;
|
|
1053
|
+
if (args.is_global) {
|
|
1054
|
+
rc = _refresh_global(runner, out, err) || rc;
|
|
1055
|
+
}
|
|
1056
|
+
if (args.is_project && rc === 0) {
|
|
1057
|
+
rc = _refresh_project(root, out, err) || rc;
|
|
1058
|
+
}
|
|
1059
|
+
return rc;
|
|
1060
|
+
}
|
|
1061
|
+
function _isCliEntry3() {
|
|
1062
|
+
if (process3.argv[1] === void 0) {
|
|
1063
|
+
return false;
|
|
1064
|
+
}
|
|
1065
|
+
const argvUrl = pathToFileURL3(path4.resolve(process3.argv[1])).href;
|
|
1066
|
+
if (import.meta.url === argvUrl) {
|
|
1067
|
+
return true;
|
|
1068
|
+
}
|
|
1069
|
+
try {
|
|
1070
|
+
const here = fs4.realpathSync(fileURLToPath4(import.meta.url));
|
|
1071
|
+
const argv = fs4.realpathSync(path4.resolve(process3.argv[1]));
|
|
1072
|
+
return here === argv;
|
|
1073
|
+
} catch {
|
|
1074
|
+
return false;
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
if (_isCliEntry3() || process3.argv[1] === _HERE3) {
|
|
1078
|
+
try {
|
|
1079
|
+
process3.exitCode = main3(process3.argv.slice(2));
|
|
1080
|
+
} catch (e) {
|
|
1081
|
+
if (e instanceof ArgparseExit) {
|
|
1082
|
+
process3.exitCode = e.code;
|
|
1083
|
+
} else {
|
|
1084
|
+
throw e;
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
export {
|
|
1090
|
+
needs_refresh,
|
|
1091
|
+
install_cli_wrapper,
|
|
1092
|
+
SECTION_HEADER2 as SECTION_HEADER,
|
|
1093
|
+
DEFAULT_GITATTRIBUTES,
|
|
1094
|
+
ArgparseExit,
|
|
1095
|
+
_remove_legacy_consumer_bridge_marker,
|
|
1096
|
+
_default_runner,
|
|
1097
|
+
_refresh_global,
|
|
1098
|
+
_is_source_repo,
|
|
1099
|
+
_refresh_project,
|
|
1100
|
+
_sync_gitignore,
|
|
1101
|
+
_sync_gitattributes,
|
|
1102
|
+
_parse,
|
|
1103
|
+
main3 as main
|
|
1104
|
+
};
|