@event4u/agent-config 17.2.1 → 17.4.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/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/skills/install-agent-config/SKILL.md +9 -9
- package/CHANGELOG.md +167 -193
- package/CREDITS.md +2 -2
- package/README.md +1 -1
- package/dist/agent-src/skills/code-intelligence/SKILL.md +16 -12
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/scripts/check_memory.ts +1 -1
- package/dist/cli/commands/recordTriggerEval.js +1 -1
- package/dist/cli/registry.js +2 -2
- package/dist/cli-delegate/{chunk-KR5ZIFPO.js → chunk-5AYJGUA3.js} +1 -3
- package/dist/cli-delegate/chunk-DIFZBP4G.js +1336 -0
- package/dist/cli-delegate/chunk-E7ACTJTJ.js +6792 -0
- package/dist/cli-delegate/{chunk-VYZGJLCA.js → chunk-RKNT4LIK.js} +22 -1286
- package/dist/cli-delegate/{chunk-BZJ4Y3CI.js → chunk-WY5ZZPGL.js} +2 -2
- package/dist/cli-delegate/{chunk-CMZEKSNN.js → chunk-X6LZ7W5A.js} +73 -10
- package/dist/cli-delegate/cmd_conformance.js +190 -192
- package/dist/cli-delegate/cmd_doctor.js +5 -5
- package/dist/cli-delegate/cmd_doctor_neighbours.js +3 -3
- package/dist/cli-delegate/cmd_explain.js +1 -1
- package/dist/cli-delegate/cmd_export.js +2 -2
- package/dist/cli-delegate/cmd_handoff.js +2 -2
- package/dist/cli-delegate/cmd_memory_get.js +1 -1
- package/dist/cli-delegate/cmd_prune.js +2 -2
- package/dist/cli-delegate/cmd_route_audit.js +1 -1
- package/dist/cli-delegate/cmd_session_recycle.js +2 -2
- package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
- package/dist/cli-delegate/cmd_settings_set.js +8 -4
- package/dist/cli-delegate/cmd_sync.js +2 -2
- package/dist/cli-delegate/cmd_uninstall.js +2 -2
- package/dist/cli-delegate/cmd_update.js +24 -13
- package/dist/cli-delegate/cmd_upgrade.js +2 -2
- package/dist/cli-delegate/cmd_validate.js +2 -2
- package/dist/cli-delegate/dist-25AZAHOP.js +3240 -0
- package/dist/cli-delegate/dist-P7MFPMF3.js +411 -0
- package/dist/cli-delegate/dist-XAS5ZLQB.js +6 -0
- package/dist/cli-delegate/{upgrade_unattended-VVL6JLSX.js → upgrade_unattended-QCWOKTUN.js} +178 -163
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +3 -3
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/code_graph_refresh.chunk.cjs +443 -0
- package/dist/hooks/code_graph_refresh.chunk.cjs.sha256 +1 -0
- package/dist/hooks/dispatch.js +1001 -938
- package/dist/hooks/dispatch.sha256 +1 -1
- package/dist/hooks/egress_engine.chunk.cjs +57 -7
- package/dist/hooks/egress_engine.chunk.cjs.sha256 +1 -1
- package/dist/hooks/update_notice.chunk.cjs +914 -0
- package/dist/hooks/update_notice.chunk.cjs.sha256 +1 -0
- package/dist/install/install.mjs +6974 -6037
- package/dist/mcp/mcp-cloudflare-catalogue.json +1 -0
- package/dist/mcp/registry-manifest.json +3 -2
- package/dist/mcp/server.json +13 -4
- package/dist/mcp/server.mjs +71202 -63282
- package/dist/scripts/_lib/egress_rules.js +8 -2
- package/dist/scripts/condense.js +18 -15
- package/dist/server/routes/discovery.js +1 -1
- package/dist/server/routes/install.js +1 -1
- package/dist/server/routes/ping.js +1 -1
- package/dist/server/routes/schema.js +4 -4
- package/dist/server/routes/settings.js +2 -6
- package/dist/server/routes/wizard.js +6 -6
- package/dist/server/schemas/settings.js +42 -42
- package/dist/shared/settingsSurface.js +1 -1
- package/dist/shared/userMd/schema.js +1 -1
- package/dist/shared/zodJsonSchema.js +47 -0
- package/dist/ui/assets/index-B0bcIgi0.js +77 -0
- package/dist/ui/index.html +1 -1
- package/package.json +6 -3
- package/src/agent-src/templates/scripts/check_memory.ts +1 -1
- package/src/config/ci-local-parity.yml +11 -0
- package/src/config/continuity-surface.json +9 -2
- package/src/config/evaluator-budgets.json +9 -8
- package/src/config/gate-violation-baselines.json +3 -3
- package/src/config/gitignore-block.txt +6 -5
- package/src/config/hook-bundle-budget.json +46 -6
- package/src/config/pack-size-budget.json +12 -1
- package/src/config/packed-binary-manifest.json +18 -0
- package/src/config/sigstore/npm_keys.json +50 -0
- package/src/config/sigstore/trust-material.json +9 -0
- package/src/config/sigstore/trusted_root.json +126 -0
- package/src/config/skill-body-budget.json +7 -1
- package/src/scripts/_cli/cmd_settings_set.ts +3 -2
- package/src/scripts/_cli/cmd_update.ts +48 -20
- package/src/scripts/_cli/cmd_upgrade.ts +7 -1
- package/src/scripts/_cli/upgrade_unattended.ts +90 -76
- package/src/scripts/_dispatch.bash +4 -3
- package/src/scripts/_lib/confusables.ts +0 -19
- package/src/scripts/_lib/egress_normalize.ts +53 -23
- package/src/scripts/_lib/egress_rules.ts +8 -2
- package/src/scripts/_lib/egress_text.ts +5 -3
- package/src/scripts/_lib/egress_token.ts +7 -5
- package/src/scripts/_lib/gate_collector_experimental.ts +633 -0
- package/src/scripts/_lib/git_common_dir.ts +10 -0
- package/src/scripts/_lib/graph_feeder_record.ts +3 -2
- package/src/scripts/_lib/install_reach_checks.ts +32 -2
- package/src/scripts/_lib/lineage_backfill.ts +136 -0
- package/src/scripts/_lib/lineage_ledger.ts +211 -0
- package/src/scripts/_lib/lineage_map.ts +55 -0
- package/src/scripts/_lib/lineage_query.ts +140 -0
- package/src/scripts/_lib/lineage_seed.ts +116 -0
- package/src/scripts/_lib/lineage_watch.ts +249 -0
- package/src/scripts/_lib/link_crypto.ts +8 -4
- package/src/scripts/_lib/listing_manifests.ts +85 -0
- package/src/scripts/_lib/neighbour_census.ts +1 -0
- package/src/scripts/_lib/production_reach.ts +3 -3
- package/src/scripts/_lib/project_registry.ts +227 -0
- package/src/scripts/_lib/provenance_verify.ts +14 -242
- package/src/scripts/_lib/release_settings_surface.ts +2 -6
- package/src/scripts/_lib/sigstore_provenance.ts +177 -0
- package/src/scripts/_lib/source_id.ts +48 -0
- package/src/scripts/_lib/source_shape.ts +4 -0
- package/src/scripts/_lib/unattended_gates.ts +6 -1
- package/src/scripts/adoption_status.ts +231 -27
- package/src/scripts/advisories.ts +26 -10
- package/src/scripts/ai_council/council_egress.ts +5 -6
- package/src/scripts/bench_graph_feeder_latency.ts +10 -3
- package/src/scripts/build_mcp_registry_manifest.ts +23 -12
- package/src/scripts/check_dependency_floors.ts +14 -0
- package/src/scripts/check_egress_mutations.ts +1 -0
- package/src/scripts/check_release_manifest_content.ts +17 -2
- package/src/scripts/check_release_pr_shape.ts +5 -0
- package/src/scripts/code_graph/build.ts +145 -45
- package/src/scripts/code_graph/cli.ts +382 -35
- package/src/scripts/code_graph/conventions_default.ts +247 -0
- package/src/scripts/code_graph/detect.ts +5 -5
- package/src/scripts/code_graph/estate_cli.ts +135 -0
- package/src/scripts/code_graph/estate_index.ts +394 -0
- package/src/scripts/code_graph/estate_manifests.ts +223 -0
- package/src/scripts/code_graph/estate_map.ts +141 -0
- package/src/scripts/code_graph/extract.ts +8 -2
- package/src/scripts/code_graph/extract_more.ts +241 -2
- package/src/scripts/code_graph/graph_budget.ts +158 -0
- package/src/scripts/code_graph/graph_home.ts +80 -0
- package/src/scripts/code_graph/lineage_cli.ts +315 -0
- package/src/scripts/code_graph/loader.ts +10 -2
- package/src/scripts/code_graph/map.ts +195 -53
- package/src/scripts/code_graph/map_model.ts +113 -20
- package/src/scripts/code_graph/map_verify.ts +80 -5
- package/src/scripts/code_graph/map_viewer/viewer.css +18 -0
- package/src/scripts/code_graph/map_viewer/viewer.js +146 -15
- package/src/scripts/code_graph/passes.ts +173 -0
- package/src/scripts/code_graph/project_ref.ts +25 -0
- package/src/scripts/code_graph/projects_cli.ts +254 -0
- package/src/scripts/code_graph/providers/angular.ts +55 -0
- package/src/scripts/code_graph/providers/aspnetcore.ts +182 -0
- package/src/scripts/code_graph/providers/catalog.ts +299 -0
- package/src/scripts/code_graph/providers/django.ts +206 -0
- package/src/scripts/code_graph/providers/express.ts +25 -0
- package/src/scripts/code_graph/providers/fastapi.ts +49 -0
- package/src/scripts/code_graph/providers/flask.ts +99 -0
- package/src/scripts/code_graph/providers/go_http.ts +121 -0
- package/src/scripts/code_graph/providers/index.ts +103 -0
- package/src/scripts/code_graph/{laravel_overlay.ts → providers/laravel.ts} +113 -7
- package/src/scripts/code_graph/providers/nestjs.ts +34 -0
- package/src/scripts/code_graph/providers/nextjs.ts +91 -0
- package/src/scripts/code_graph/providers/nuxt.ts +55 -0
- package/src/scripts/code_graph/providers/rails.ts +204 -0
- package/src/scripts/code_graph/providers/react-router.ts +58 -0
- package/src/scripts/code_graph/providers/shared/detect.ts +78 -0
- package/src/scripts/code_graph/providers/shared/extractors.ts +249 -0
- package/src/scripts/code_graph/providers/shared/js.ts +252 -0
- package/src/scripts/code_graph/providers/shared/kit.ts +210 -0
- package/src/scripts/code_graph/providers/shared/php.ts +64 -0
- package/src/scripts/code_graph/providers/shared/python.ts +223 -0
- package/src/scripts/code_graph/providers/spring.ts +175 -0
- package/src/scripts/code_graph/providers/sqlalchemy.ts +62 -0
- package/src/scripts/code_graph/providers/sveltekit.ts +59 -0
- package/src/scripts/code_graph/providers/symfony.ts +142 -0
- package/src/scripts/code_graph/providers/typeorm.ts +58 -0
- package/src/scripts/code_graph/providers/types.ts +56 -0
- package/src/scripts/code_graph/providers/vue-router.ts +21 -0
- package/src/scripts/code_graph/providers/wordpress.ts +128 -0
- package/src/scripts/code_graph/query.ts +9 -9
- package/src/scripts/code_graph/refresh_cli.ts +81 -0
- package/src/scripts/code_graph/refresh_lock.ts +197 -0
- package/src/scripts/code_graph/repo_identity.ts +169 -0
- package/src/scripts/code_graph/resolution_tiers.ts +19 -7
- package/src/scripts/code_graph/scip_reader.ts +2 -2
- package/src/scripts/code_graph/sqlite_store.ts +31 -28
- package/src/scripts/code_graph/types.ts +79 -41
- package/src/scripts/code_graph/validate.ts +6 -8
- package/src/scripts/condense.ts +15 -15
- package/src/scripts/generate_settings_reference.ts +2 -6
- package/src/scripts/hook_chunks.mjs +11 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +43 -23
- package/src/scripts/hooks/code_graph_refresh_hook.ts +163 -0
- package/src/scripts/hooks/dispatch_hook.ts +6 -7
- package/src/scripts/hooks/host_semantics.ts +72 -0
- package/src/scripts/hooks/lazy_concern.ts +8 -0
- package/src/scripts/hooks/user_notice.ts +105 -0
- package/src/scripts/install-hooks.sh +54 -33
- package/src/scripts/install.ts +2 -6
- package/src/scripts/lint_harvest_provenance.ts +137 -11
- package/src/scripts/lint_hook_manifest.ts +2 -0
- package/src/scripts/lint_marketplace.ts +33 -0
- package/src/scripts/lint_mcp_registry_manifest.ts +36 -0
- package/src/scripts/mcp_server/consumer_tool_catalog.json +70 -15
- package/src/scripts/mcp_server/graph_tools.ts +165 -41
- package/src/scripts/network_sources.ts +24 -6
- package/src/scripts/release.ts +2 -5
- package/src/scripts/release_drill.ts +4 -1
- package/src/scripts/release_env.ts +17 -0
- package/src/scripts/release_mix_taxonomy.json +3 -0
- package/src/scripts/schemas/provenance-mechanism.schema.json +46 -0
- package/src/scripts/update_notice_hook.ts +75 -7
- package/src/server/schemas/settings.ts +42 -42
- package/src/shared/settingsSurface.ts +1 -1
- package/src/shared/userMd/schema.ts +1 -1
- package/src/shared/zodJsonSchema.ts +41 -0
- package/src/vendor/grammars/README.md +8 -6
- package/src/vendor/grammars/tree-sitter-c_sharp.wasm +0 -0
- package/src/vendor/grammars/tree-sitter-ruby.wasm +0 -0
- package/dist/cli-delegate/chunk-XIAPY44N.js +0 -4587
- package/dist/ui/assets/index-w70Ado09.js +0 -23
- /package/dist/cli-delegate/{chunk-FKYZOWVD.js → chunk-QBAFP67O.js} +0 -0
- /package/dist/cli-delegate/{chunk-BMGUGSY6.js → chunk-TQG6UMPC.js} +0 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a root's graph, map and refresh lock live (ADR-299).
|
|
3
|
+
*
|
|
4
|
+
* A root that has `agents/` or a project install keeps today's paths under
|
|
5
|
+
* `<root>/agents/`, byte-identical, so a map shared through the repository is
|
|
6
|
+
* unchanged. Every other root gets a home under the user-global
|
|
7
|
+
* `runtime/graphs/<repo id>-<checkout | instance>/`, so building a graph of
|
|
8
|
+
* somebody else's repository writes nothing into it, and two clones of one
|
|
9
|
+
* origin never share a cache, lock or budget slot. Resolving never creates `agents/`.
|
|
10
|
+
*/
|
|
11
|
+
import * as fs from 'node:fs';
|
|
12
|
+
import * as path from 'node:path';
|
|
13
|
+
|
|
14
|
+
import { type EnvMap, event4u_root } from '../_lib/user_global_paths.js';
|
|
15
|
+
import { repoIdentity } from './repo_identity.js';
|
|
16
|
+
|
|
17
|
+
export const STATE_DIR_REL = path.join('agents', 'runtime', 'state');
|
|
18
|
+
export const NATIVE_CACHE_REL = path.join(STATE_DIR_REL, 'code-graph-v1.json');
|
|
19
|
+
export const MAP_DIR_REL = path.join('agents', 'map');
|
|
20
|
+
export const LOCK_REL = path.join(STATE_DIR_REL, 'code-graph-refresh.lock');
|
|
21
|
+
/** Written by `code-graph auto-refresh on`; the session concern acts only while it exists. */
|
|
22
|
+
export const AUTO_REFRESH_REL = path.join(STATE_DIR_REL, 'code-graph-auto-refresh.json');
|
|
23
|
+
|
|
24
|
+
export interface GraphHome {
|
|
25
|
+
kind: 'project' | 'global';
|
|
26
|
+
root: string;
|
|
27
|
+
/** `<root>/agents` for a project home, the per-repository directory otherwise. */
|
|
28
|
+
dir: string;
|
|
29
|
+
stateDir: string;
|
|
30
|
+
cachePath: string;
|
|
31
|
+
mapDir: string;
|
|
32
|
+
lockPath: string;
|
|
33
|
+
autoRefreshPath: string;
|
|
34
|
+
repoId: string | null;
|
|
35
|
+
instance: string | null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function graphsRoot(env?: EnvMap | null): string {
|
|
39
|
+
return path.join(event4u_root(env), 'runtime', 'graphs');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** `agents/` exists, or the installer's settings file marks a project install. */
|
|
43
|
+
export function hasProjectHome(root: string): boolean {
|
|
44
|
+
return fs.existsSync(path.join(root, 'agents')) || fs.existsSync(path.join(root, '.agent-settings.yml'));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Today's in-repository paths; callers that serve project homes only use this alone. */
|
|
48
|
+
export function projectHome(root: string): GraphHome {
|
|
49
|
+
return {
|
|
50
|
+
kind: 'project',
|
|
51
|
+
root,
|
|
52
|
+
dir: path.join(root, 'agents'),
|
|
53
|
+
stateDir: path.join(root, STATE_DIR_REL),
|
|
54
|
+
cachePath: path.join(root, NATIVE_CACHE_REL),
|
|
55
|
+
mapDir: path.join(root, MAP_DIR_REL),
|
|
56
|
+
lockPath: path.join(root, LOCK_REL),
|
|
57
|
+
autoRefreshPath: path.join(root, AUTO_REFRESH_REL),
|
|
58
|
+
repoId: null,
|
|
59
|
+
instance: null,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function graphHome(root: string, env?: EnvMap | null): GraphHome {
|
|
64
|
+
if (hasProjectHome(root)) return projectHome(root);
|
|
65
|
+
const id = repoIdentity(root, env);
|
|
66
|
+
const dir = path.join(graphsRoot(env), `${id.repoId}-${id.instance ?? id.checkout}`);
|
|
67
|
+
const stateDir = path.join(dir, 'state');
|
|
68
|
+
return {
|
|
69
|
+
kind: 'global',
|
|
70
|
+
root,
|
|
71
|
+
dir,
|
|
72
|
+
stateDir,
|
|
73
|
+
cachePath: path.join(stateDir, path.basename(NATIVE_CACHE_REL)),
|
|
74
|
+
mapDir: path.join(dir, 'map'),
|
|
75
|
+
lockPath: path.join(stateDir, path.basename(LOCK_REL)),
|
|
76
|
+
autoRefreshPath: path.join(stateDir, path.basename(AUTO_REFRESH_REL)),
|
|
77
|
+
repoId: id.repoId,
|
|
78
|
+
instance: id.instance,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `code-graph lineage <verb>` — where harvested mechanisms came from, and what is still missing.
|
|
3
|
+
*
|
|
4
|
+
* Two ledgers answer, never one (council O5): the tracked, source-free decision ledger
|
|
5
|
+
* `provenance/mechanisms.jsonl` of the repo at `--root`, and the local source ledger under
|
|
6
|
+
* the user-global `runtime/lineage/` (`_lib/lineage_ledger.ts`). A verb that needs the
|
|
7
|
+
* local side and the key refuses without them instead of answering from half the data.
|
|
8
|
+
*
|
|
9
|
+
* Exit codes: 0 ok · 1 findings · 2 usage or refused.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import * as fs from 'node:fs';
|
|
13
|
+
import * as path from 'node:path';
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
assertOutsideWorkTree,
|
|
17
|
+
checkLedger,
|
|
18
|
+
hasLedger,
|
|
19
|
+
LineageError,
|
|
20
|
+
lineageDir,
|
|
21
|
+
mergeIntoLedger,
|
|
22
|
+
readLedger,
|
|
23
|
+
writeLedger,
|
|
24
|
+
writePrivateFile,
|
|
25
|
+
} from '../_lib/lineage_ledger.js';
|
|
26
|
+
import { BACKFILL_DIR_REL, isIgnored, scanTree, writeBackfill } from '../_lib/lineage_backfill.js';
|
|
27
|
+
import { LINEAGE_VIEW_REL, renderSourceLineage, renderTrackedLineage } from '../_lib/lineage_map.js';
|
|
28
|
+
import { refuseUnderCi, renderWatchReport, renderWatchStub, runWatch, systemGit } from '../_lib/lineage_watch.js';
|
|
29
|
+
import { gaps, lineageFrom, lineageOf, readDecisions, rejected } from '../_lib/lineage_query.js';
|
|
30
|
+
import { buildLocalImport } from '../_lib/lineage_seed.js';
|
|
31
|
+
import { resolve_keys } from '../_lib/link_crypto.js';
|
|
32
|
+
import type { EnvMap } from '../_lib/user_global_paths.js';
|
|
33
|
+
|
|
34
|
+
export interface LineageDeps {
|
|
35
|
+
readonly env?: EnvMap;
|
|
36
|
+
/** Link keys; resolved from settings when absent. Tests pass them explicitly. */
|
|
37
|
+
readonly keys?: readonly string[];
|
|
38
|
+
readonly now?: () => Date;
|
|
39
|
+
readonly stdout?: (s: string) => void;
|
|
40
|
+
readonly stderr?: (s: string) => void;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface Io {
|
|
44
|
+
readonly env: EnvMap;
|
|
45
|
+
readonly root: string;
|
|
46
|
+
readonly keys: () => readonly string[];
|
|
47
|
+
readonly now: () => Date;
|
|
48
|
+
readonly out: (s: string) => void;
|
|
49
|
+
readonly err: (s: string) => void;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function flag(argv: readonly string[], name: string): string | undefined {
|
|
53
|
+
const i = argv.indexOf(name);
|
|
54
|
+
return i === -1 ? undefined : argv[i + 1];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function cmdCheck(io: Io): number {
|
|
58
|
+
const dir = lineageDir(io.env);
|
|
59
|
+
if (!hasLedger(dir)) {
|
|
60
|
+
io.err(`code-graph lineage: no local lineage ledger at ${dir} — run \`code-graph lineage import\` first\n`);
|
|
61
|
+
return 2;
|
|
62
|
+
}
|
|
63
|
+
const findings = checkLedger(dir, io.keys());
|
|
64
|
+
const { sources, edges } = readLedger(dir);
|
|
65
|
+
if (findings.length > 0) {
|
|
66
|
+
for (const f of findings) io.err(`${f.file}:${String(f.line)} ${f.message}\n`);
|
|
67
|
+
io.err(`code-graph lineage check: ${String(findings.length)} finding(s)\n`);
|
|
68
|
+
return 1;
|
|
69
|
+
}
|
|
70
|
+
io.out(`code-graph lineage check: ${String(sources.length)} source(s), ${String(edges.length)} edge(s) OK at ${dir}\n`);
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Refuse, naming the setting, when no link key is configured. */
|
|
75
|
+
export function needKeys(io: Io, verb: string): readonly string[] | null {
|
|
76
|
+
const keys = io.keys();
|
|
77
|
+
if (keys.length > 0) return keys;
|
|
78
|
+
io.err(
|
|
79
|
+
`code-graph lineage ${verb}: no link_encryption_key configured (secrets.link_encryption_key) — ` +
|
|
80
|
+
'the local ledger is sealed with it, so nothing is read or written without it\n',
|
|
81
|
+
);
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function cmdImport(io: Io): number {
|
|
86
|
+
const keys = needKeys(io, 'import');
|
|
87
|
+
if (keys === null) return 2;
|
|
88
|
+
const { ledger, refused } = buildLocalImport(io.root, keys);
|
|
89
|
+
const dir = lineageDir(io.env);
|
|
90
|
+
const added = mergeIntoLedger(dir, ledger, keys);
|
|
91
|
+
for (const r of refused) io.err(`code-graph lineage import: skipped ${r}\n`);
|
|
92
|
+
io.out(
|
|
93
|
+
`code-graph lineage import: ${String(added.sources)} new source(s), ${String(added.edges)} new edge(s) into ${dir}` +
|
|
94
|
+
`${refused.length > 0 ? ` · ${String(refused.length)} skipped` : ''}\n`,
|
|
95
|
+
);
|
|
96
|
+
return refused.length > 0 ? 1 : 0;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** The graph's node lookup for `root`, or null when no graph has been built. */
|
|
100
|
+
async function graphLookup(io: Io, explicit: string | undefined): Promise<{ has(id: string): boolean } | null> {
|
|
101
|
+
// Dynamic: cli.ts dispatches into this module, and the default cache path is its to own.
|
|
102
|
+
const graphPath = explicit ?? (await import('./cli.js')).cacheFor(io.root);
|
|
103
|
+
if (!fs.existsSync(graphPath)) return null;
|
|
104
|
+
const { loadGraph } = await import('./query.js');
|
|
105
|
+
return loadGraph(graphPath).byId;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
async function cmdOf(io: Io, query: string | undefined, graphFlag: string | undefined): Promise<number> {
|
|
109
|
+
if (query === undefined || query.startsWith('--')) {
|
|
110
|
+
io.err('usage: code-graph lineage of <mechanism-id|path> [--root P] [--graph P]\n');
|
|
111
|
+
return 2;
|
|
112
|
+
}
|
|
113
|
+
const entries = lineageOf(io.root, query, await graphLookup(io, graphFlag));
|
|
114
|
+
if (entries.length === 0) {
|
|
115
|
+
io.err(`code-graph lineage of: no mechanism matches ${query} in provenance/mechanisms.jsonl\n`);
|
|
116
|
+
return 1;
|
|
117
|
+
}
|
|
118
|
+
let broken = 0;
|
|
119
|
+
for (const e of entries) {
|
|
120
|
+
io.out(`${e.mechanism_id} ${e.verdict} ${e.decided_at} (${String(e.decisions)} decision(s))\n`);
|
|
121
|
+
for (const r of e.realised) {
|
|
122
|
+
if (r.status === 'broken') broken += 1;
|
|
123
|
+
const g = r.in_graph === null ? 'no graph built' : r.in_graph ? 'indexed' : 'not indexed';
|
|
124
|
+
io.out(` realised_in ${r.path} ${r.status === 'ok' ? 'ok' : 'BROKEN'} graph: ${g}\n`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (broken > 0) io.err(`code-graph lineage of: ${String(broken)} broken edge(s) — the file moved or is gone\n`);
|
|
128
|
+
return broken > 0 ? 1 : 0;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function cmdGaps(io: Io): number {
|
|
132
|
+
const view = gaps(readDecisions(io.root));
|
|
133
|
+
for (const g of view) {
|
|
134
|
+
io.out(`${g.mechanism_id} ${g.verdict} ${g.owner}${g.reopen_if ? ` reopen if: ${g.reopen_if}` : ''}\n`);
|
|
135
|
+
}
|
|
136
|
+
io.out(`code-graph lineage gaps: ${String(view.length)} open mechanism(s)\n`);
|
|
137
|
+
return 0;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function cmdRejected(io: Io): number {
|
|
141
|
+
const view = rejected(readDecisions(io.root));
|
|
142
|
+
for (const r of view) {
|
|
143
|
+
io.out(`${r.mechanism_id} ${r.reason ?? ''}${r.reopen_if ? ` reopen if: ${r.reopen_if}` : ''}\n`);
|
|
144
|
+
}
|
|
145
|
+
io.out(`code-graph lineage rejected: ${String(view.length)} rejected mechanism(s)\n`);
|
|
146
|
+
return 0;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function cmdFrom(io: Io, query: string | undefined): number {
|
|
150
|
+
if (query === undefined || query.startsWith('--')) {
|
|
151
|
+
io.err('usage: code-graph lineage from <source-id|identity> [--root P]\n');
|
|
152
|
+
return 2;
|
|
153
|
+
}
|
|
154
|
+
const dir = lineageDir(io.env);
|
|
155
|
+
if (!hasLedger(dir)) {
|
|
156
|
+
io.err(`code-graph lineage from: no local lineage ledger at ${dir} — the source side exists only on the owner's machine\n`);
|
|
157
|
+
return 2;
|
|
158
|
+
}
|
|
159
|
+
const keys = needKeys(io, 'from');
|
|
160
|
+
if (keys === null) return 2;
|
|
161
|
+
const found = lineageFrom(readLedger(dir), query, keys, readDecisions(io.root));
|
|
162
|
+
if (found === null) {
|
|
163
|
+
io.err('code-graph lineage from: no such source in the local ledger\n');
|
|
164
|
+
return 1;
|
|
165
|
+
}
|
|
166
|
+
io.out(`${found.source.source_id} ${found.source.kind} ${found.identity} license ${found.source.license} watch ${found.source.watch ? 'on' : 'off'}\n`);
|
|
167
|
+
for (const m of found.mechanisms) {
|
|
168
|
+
io.out(` ${m.mechanism_id} ${m.verdict ?? '(no decision)'} pin ${m.pin}${m.locator ? ` at ${m.locator}` : ''}\n`);
|
|
169
|
+
}
|
|
170
|
+
return 0;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* `map --lineage` (tracked view, verdicts only) or `map --lineage --sources` (local view).
|
|
175
|
+
* The tracked view is written only into a repo that already has `agents/`, so a foreign
|
|
176
|
+
* repository never gains a directory from it.
|
|
177
|
+
*/
|
|
178
|
+
function cmdMap(io: Io, argv: readonly string[]): number {
|
|
179
|
+
const outFlag = flag(argv, '--out');
|
|
180
|
+
if (argv.includes('--sources')) {
|
|
181
|
+
const out = path.resolve(outFlag ?? path.join(lineageDir(io.env), 'map', 'sources.md'));
|
|
182
|
+
assertOutsideWorkTree(out);
|
|
183
|
+
const dir = lineageDir(io.env);
|
|
184
|
+
if (!hasLedger(dir)) {
|
|
185
|
+
io.err(`code-graph lineage map --sources: no local lineage ledger at ${dir}\n`);
|
|
186
|
+
return 2;
|
|
187
|
+
}
|
|
188
|
+
const keys = needKeys(io, 'map --sources');
|
|
189
|
+
if (keys === null) return 2;
|
|
190
|
+
writePrivateFile(out, renderSourceLineage(readLedger(dir), keys, readDecisions(io.root)));
|
|
191
|
+
io.out(`code-graph lineage map: source view written to ${out}\n`);
|
|
192
|
+
return 0;
|
|
193
|
+
}
|
|
194
|
+
const out = path.resolve(outFlag ?? path.join(io.root, LINEAGE_VIEW_REL));
|
|
195
|
+
if (outFlag === undefined && !fs.existsSync(path.join(io.root, 'agents'))) {
|
|
196
|
+
io.err(`code-graph lineage map: ${io.root} has no agents/ directory — pass --out to choose where the view goes\n`);
|
|
197
|
+
return 2;
|
|
198
|
+
}
|
|
199
|
+
fs.mkdirSync(path.dirname(out), { recursive: true });
|
|
200
|
+
fs.writeFileSync(out, renderTrackedLineage(readDecisions(io.root)));
|
|
201
|
+
io.out(`code-graph lineage map: tracked view written to ${out}\n`);
|
|
202
|
+
return 0;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
function cmdBackfill(io: Io, argv: readonly string[]): number {
|
|
206
|
+
if (!argv.includes('--draft')) {
|
|
207
|
+
io.err('code-graph lineage backfill: only --draft exists — the backfill proposes drafts and never writes a ledger row\n');
|
|
208
|
+
return 2;
|
|
209
|
+
}
|
|
210
|
+
if (!isIgnored(io.root, BACKFILL_DIR_REL)) {
|
|
211
|
+
io.err(`code-graph lineage backfill: ${BACKFILL_DIR_REL}/ is not ignored by git in ${io.root} — decrypted identities would become trackable\n`);
|
|
212
|
+
return 2;
|
|
213
|
+
}
|
|
214
|
+
const keys = needKeys(io, 'backfill');
|
|
215
|
+
if (keys === null) return 2;
|
|
216
|
+
const result = scanTree(io.root, keys);
|
|
217
|
+
const out = writeBackfill(io.root, result);
|
|
218
|
+
for (const u of result.unclear) io.out(`unclear ${u}\n`);
|
|
219
|
+
for (const u of result.undecryptable) io.out(`undecryptable ${u}\n`);
|
|
220
|
+
io.out(
|
|
221
|
+
`code-graph lineage backfill: ${String(result.drafts.length)} draft(s), ${String(result.unclear.length)} unclear, ` +
|
|
222
|
+
`${String(result.undecryptable.length)} undecryptable — written to ${out}; no ledger row written\n`,
|
|
223
|
+
);
|
|
224
|
+
return 0;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function cmdWatchFlag(io: Io, on: boolean, id: string | undefined): number {
|
|
228
|
+
const dir = lineageDir(io.env);
|
|
229
|
+
if (id === undefined || !hasLedger(dir)) {
|
|
230
|
+
io.err(`usage: code-graph lineage watch ${on ? 'enable' : 'disable'} <source-id> (needs the local ledger at ${dir})\n`);
|
|
231
|
+
return 2;
|
|
232
|
+
}
|
|
233
|
+
const ledger = readLedger(dir);
|
|
234
|
+
const hit = ledger.sources.find((s) => s.source_id === id);
|
|
235
|
+
if (hit === undefined) {
|
|
236
|
+
io.err(`code-graph lineage watch: no source ${id} in the local ledger\n`);
|
|
237
|
+
return 1;
|
|
238
|
+
}
|
|
239
|
+
writeLedger(dir, { sources: ledger.sources.map((s) => (s.source_id === id ? { ...s, watch: on } : s)), edges: ledger.edges });
|
|
240
|
+
io.out(`code-graph lineage watch: ${id} ${on ? 'on' : 'off'}\n`);
|
|
241
|
+
return 0;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function cmdWatch(io: Io, argv: readonly string[]): number {
|
|
245
|
+
if (argv[1] === 'enable' || argv[1] === 'disable') return cmdWatchFlag(io, argv[1] === 'enable', argv[2]);
|
|
246
|
+
refuseUnderCi(io.env);
|
|
247
|
+
const dir = lineageDir(io.env);
|
|
248
|
+
if (!hasLedger(dir)) {
|
|
249
|
+
io.err(`code-graph lineage watch: no local lineage ledger at ${dir}\n`);
|
|
250
|
+
return 2;
|
|
251
|
+
}
|
|
252
|
+
const keys = needKeys(io, 'watch');
|
|
253
|
+
if (keys === null) return 2;
|
|
254
|
+
const reports = runWatch({ dir, keys, rows: readDecisions(io.root), git: systemGit, env: io.env });
|
|
255
|
+
for (const r of reports) {
|
|
256
|
+
io.out(`${r.source_id} ${r.status}${r.note ? ` ${r.note}` : ''}\n`);
|
|
257
|
+
for (const f of r.findings) io.out(` ${f.class} ${f.mechanism_id ?? '(no mechanism)'} ${f.locator}\n`);
|
|
258
|
+
}
|
|
259
|
+
io.out(`code-graph lineage watch: ${String(reports.length)} watched source(s)\n`);
|
|
260
|
+
if (argv.includes('--dry-run')) return 0;
|
|
261
|
+
|
|
262
|
+
const date = io.now().toISOString().slice(0, 10);
|
|
263
|
+
if (reports.length > 0) {
|
|
264
|
+
const reportPath = path.join(dir, 'watch', `report-${date}.md`);
|
|
265
|
+
writePrivateFile(reportPath, renderWatchReport(reports, date));
|
|
266
|
+
io.out(`code-graph lineage watch: report written to ${reportPath}\n`);
|
|
267
|
+
}
|
|
268
|
+
const stub = renderWatchStub(reports, date, keys[0] as string);
|
|
269
|
+
if (stub === null) return 0;
|
|
270
|
+
const stubDir = path.join(io.root, 'agents', 'roadmaps', 'stubs');
|
|
271
|
+
if (!fs.existsSync(stubDir)) {
|
|
272
|
+
io.err(`code-graph lineage watch: ${io.root} has no agents/roadmaps/stubs/ — the stub was not written\n`);
|
|
273
|
+
return 2;
|
|
274
|
+
}
|
|
275
|
+
const stubPath = path.join(stubDir, `road-to-lineage-delta-${date}.md`);
|
|
276
|
+
fs.writeFileSync(stubPath, stub);
|
|
277
|
+
io.out(`code-graph lineage watch: stub written to ${stubPath}\n`);
|
|
278
|
+
return 0;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const USAGE = 'usage: code-graph lineage <check|import|of|gaps|rejected|from|map|backfill|watch> [args] [--root P]\n';
|
|
282
|
+
|
|
283
|
+
export async function main(argv: readonly string[], deps: LineageDeps = {}): Promise<number> {
|
|
284
|
+
const env = deps.env ?? process.env;
|
|
285
|
+
const root = path.resolve(flag(argv, '--root') ?? process.cwd());
|
|
286
|
+
let cached: readonly string[] | null = null;
|
|
287
|
+
const io: Io = {
|
|
288
|
+
env,
|
|
289
|
+
root,
|
|
290
|
+
keys: () => (cached ??= deps.keys ?? resolve_keys(root)),
|
|
291
|
+
now: deps.now ?? (() => new Date()),
|
|
292
|
+
out: deps.stdout ?? ((s) => void process.stdout.write(s)),
|
|
293
|
+
err: deps.stderr ?? ((s) => void process.stderr.write(s)),
|
|
294
|
+
};
|
|
295
|
+
const verb = argv[0];
|
|
296
|
+
try {
|
|
297
|
+
if (verb === 'check') return cmdCheck(io);
|
|
298
|
+
if (verb === 'import') return cmdImport(io);
|
|
299
|
+
if (verb === 'of') return await cmdOf(io, argv[1], flag(argv, '--graph'));
|
|
300
|
+
if (verb === 'gaps') return cmdGaps(io);
|
|
301
|
+
if (verb === 'rejected') return cmdRejected(io);
|
|
302
|
+
if (verb === 'from') return cmdFrom(io, argv[1]);
|
|
303
|
+
if (verb === 'map') return cmdMap(io, argv);
|
|
304
|
+
if (verb === 'backfill') return cmdBackfill(io, argv);
|
|
305
|
+
if (verb === 'watch') return cmdWatch(io, argv);
|
|
306
|
+
} catch (e) {
|
|
307
|
+
if (e instanceof LineageError) {
|
|
308
|
+
io.err(`code-graph lineage: ${e.message}\n`);
|
|
309
|
+
return 2;
|
|
310
|
+
}
|
|
311
|
+
throw e;
|
|
312
|
+
}
|
|
313
|
+
io.err(USAGE);
|
|
314
|
+
return 2;
|
|
315
|
+
}
|
|
@@ -146,16 +146,24 @@ async function _init(): Promise<void> {
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Grammars the pinned `tree-sitter-wasms` compiles at another ABI than the rest.
|
|
151
|
+
* The C# grammar ships at ABI 13, which the pinned runtime still loads; the pin
|
|
152
|
+
* stays exact per language, so a drift is still caught.
|
|
153
|
+
*/
|
|
154
|
+
export const GRAMMAR_ABI_PIN: Readonly<Partial<Record<Lang, number>>> = { csharp: 13 };
|
|
155
|
+
|
|
149
156
|
/** Load (and cache) a grammar; asserts the ABI matches the pinned expectation. */
|
|
150
157
|
export async function loadLanguage(lang: Lang): Promise<TsLanguage> {
|
|
151
158
|
const cached = _langCache.get(lang);
|
|
152
159
|
if (cached) return cached;
|
|
153
160
|
await _init();
|
|
154
161
|
const language = await _Parser().Language.load(grammarWasmPath(lang));
|
|
155
|
-
|
|
162
|
+
const pinned = GRAMMAR_ABI_PIN[lang] ?? EXPECTED_GRAMMAR_ABI;
|
|
163
|
+
if (language.version !== pinned) {
|
|
156
164
|
throw new Error(
|
|
157
165
|
`code-graph: grammar ABI drift for ${lang} — got ${language.version}, ` +
|
|
158
|
-
`pinned ${
|
|
166
|
+
`pinned ${pinned}. Re-pin web-tree-sitter/tree-sitter-wasms ` +
|
|
159
167
|
`and re-run the ABI smoke test.`,
|
|
160
168
|
);
|
|
161
169
|
}
|