@nodesify/astria 1.0.0 → 1.0.2
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/LICENSE +21 -21
- package/README.md +65 -65
- package/dist/commands/add.d.ts +7 -7
- package/dist/commands/add.js +33 -33
- package/dist/commands/affected.d.ts +5 -5
- package/dist/commands/affected.js +29 -29
- package/dist/commands/cluster.d.ts +1 -1
- package/dist/commands/cluster.js +50 -50
- package/dist/commands/diagnose.d.ts +4 -4
- package/dist/commands/diagnose.js +19 -19
- package/dist/commands/diff.d.ts +1 -1
- package/dist/commands/diff.js +35 -35
- package/dist/commands/explain.d.ts +3 -3
- package/dist/commands/explain.js +37 -37
- package/dist/commands/export.d.ts +6 -6
- package/dist/commands/export.js +32 -32
- package/dist/commands/feedback.d.ts +11 -11
- package/dist/commands/feedback.js +40 -40
- package/dist/commands/global.d.ts +6 -6
- package/dist/commands/global.js +60 -60
- package/dist/commands/history.d.ts +4 -4
- package/dist/commands/history.js +27 -27
- package/dist/commands/hook-guard.d.ts +1 -1
- package/dist/commands/hook-guard.js +144 -144
- package/dist/commands/hook.d.ts +2 -2
- package/dist/commands/hook.js +52 -52
- package/dist/commands/install.d.ts +2 -2
- package/dist/commands/install.js +39 -39
- package/dist/commands/map.d.ts +5 -5
- package/dist/commands/map.js +15 -15
- package/dist/commands/mcp.d.ts +3 -3
- package/dist/commands/mcp.js +14 -14
- package/dist/commands/merge.d.ts +1 -1
- package/dist/commands/merge.js +50 -50
- package/dist/commands/migrate.d.ts +3 -3
- package/dist/commands/migrate.js +74 -74
- package/dist/commands/path.d.ts +5 -5
- package/dist/commands/path.js +18 -18
- package/dist/commands/prs.d.ts +4 -4
- package/dist/commands/prs.js +132 -132
- package/dist/commands/query.d.ts +9 -9
- package/dist/commands/query.js +21 -21
- package/dist/commands/run.d.ts +9 -9
- package/dist/commands/run.js +68 -68
- package/dist/commands/stats.d.ts +3 -3
- package/dist/commands/stats.js +17 -17
- package/dist/commands/status.d.ts +3 -3
- package/dist/commands/status.js +56 -56
- package/dist/commands/tree.d.ts +5 -5
- package/dist/commands/tree.js +52 -52
- package/dist/commands/update.d.ts +6 -6
- package/dist/commands/update.js +65 -65
- package/dist/commands/watch.d.ts +3 -3
- package/dist/commands/watch.js +113 -113
- package/dist/commands/wiki.d.ts +6 -6
- package/dist/commands/wiki.js +59 -59
- package/dist/index.d.ts +4 -4
- package/dist/index.js +249 -249
- package/dist/install/hooks.d.ts +11 -11
- package/dist/install/hooks.js +306 -306
- package/dist/install/index.d.ts +2 -2
- package/dist/install/index.js +361 -361
- package/dist/install/markdown-inject.d.ts +6 -6
- package/dist/install/markdown-inject.js +177 -177
- package/dist/install/platforms.d.ts +12 -12
- package/dist/install/platforms.js +129 -129
- package/dist/install/settings-inject.d.ts +17 -17
- package/dist/install/settings-inject.js +424 -424
- package/dist/native.d.ts +31 -31
- package/dist/native.js +106 -106
- package/package.json +72 -72
- package/skills/skill-aider.md +40 -40
- package/skills/skill-codex.md +46 -46
- package/skills/skill-copilot.md +46 -46
- package/skills/skill-cursor.md +39 -39
- package/skills/skill-gemini.md +46 -46
- package/skills/skill-kiro.md +39 -39
- package/skills/skill-opencode.md +44 -44
- package/skills/skill-trae.md +46 -46
- package/skills/skill.md +266 -266
- package/dist/graphify.node +0 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export type SectionResult = 'added' | 'updated' | 'unchanged';
|
|
2
|
-
export declare const SECTION_MARKER = "<!-- astria:managed -->";
|
|
3
|
-
export declare function injectSection(filePath: string, content: string): SectionResult;
|
|
4
|
-
export declare function removeSection(filePath: string): boolean;
|
|
5
|
-
export declare const PROJECT_MD_SECTION = "## astria\n\nThis project has an astria knowledge graph at .astria/.\nAccess it through whichever path your agent has:\n- MCP (when an astria MCP server is connected): repo_map, query_graph, explain,\n get_neighbors, shortest_path, affected.\n- CLI (works everywhere): astria map, query, explain, path, affected.\n\nAlways-on behaviors:\n1. Prefer the graph over repeated text searches for architecture questions, feature\n location, cross-file logic flow, and change impact; orient with repo_map (or map,\n or .astria/graph_report.md), and run affected <node> before changing a shared symbol.\n2. Before running grep/ripgrep to locate code, try astria query first --\n it answers with file:line provenance in one call against the already-built graph.\n3. After modifying code, run astria update . (AST-only, no API cost) so the\n graph stays fresh; queries then report accurate staleness metadata.";
|
|
6
|
-
export declare const SKILL_REGISTRATION = "\n# astria\n- **astria** (`~/.claude/skills/astria/SKILL.md`) - any input to knowledge graph. Trigger: `/astria`\nWhen the user types `/astria`, invoke the Skill tool with `skill: \"astria\"` before doing anything else.\n";
|
|
1
|
+
export type SectionResult = 'added' | 'updated' | 'unchanged';
|
|
2
|
+
export declare const SECTION_MARKER = "<!-- astria:managed -->";
|
|
3
|
+
export declare function injectSection(filePath: string, content: string): SectionResult;
|
|
4
|
+
export declare function removeSection(filePath: string): boolean;
|
|
5
|
+
export declare const PROJECT_MD_SECTION = "## astria\n\nThis project has an astria knowledge graph at .astria/.\nAccess it through whichever path your agent has:\n- MCP (when an astria MCP server is connected): repo_map, query_graph, explain,\n get_neighbors, shortest_path, affected.\n- CLI (works everywhere): astria map, query, explain, path, affected.\n\nAlways-on behaviors:\n1. Prefer the graph over repeated text searches for architecture questions, feature\n location, cross-file logic flow, and change impact; orient with repo_map (or map,\n or .astria/graph_report.md), and run affected <node> before changing a shared symbol.\n2. Before running grep/ripgrep to locate code, try astria query first --\n it answers with file:line provenance in one call against the already-built graph.\n3. After modifying code, run astria update . (AST-only, no API cost) so the\n graph stays fresh; queries then report accurate staleness metadata.";
|
|
6
|
+
export declare const SKILL_REGISTRATION = "\n# astria\n- **astria** (`~/.claude/skills/astria/SKILL.md`) - any input to knowledge graph. Trigger: `/astria`\nWhen the user types `/astria`, invoke the Skill tool with `skill: \"astria\"` before doing anything else.\n";
|
|
7
7
|
//# sourceMappingURL=markdown-inject.d.ts.map
|
|
@@ -1,178 +1,178 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.SKILL_REGISTRATION = exports.PROJECT_MD_SECTION = exports.SECTION_MARKER = void 0;
|
|
37
|
-
exports.injectSection = injectSection;
|
|
38
|
-
exports.removeSection = removeSection;
|
|
39
|
-
const fs = __importStar(require("fs"));
|
|
40
|
-
const path = __importStar(require("path"));
|
|
41
|
-
// Managed sections carry this marker so later installs can refresh them
|
|
42
|
-
// wholesale. Sections are recognized two ways: by this marker, or by a
|
|
43
|
-
// legacy fingerprint. Pre-1.0 installs wrote `## graphify` sections under
|
|
44
|
-
// the old `nodesify-graphify:managed` marker — install upgrades them in
|
|
45
|
-
// place and uninstall removes them. Anything else containing a heading is
|
|
46
|
-
// treated as user-owned and left untouched.
|
|
47
|
-
exports.SECTION_MARKER = '<!-- astria:managed -->';
|
|
48
|
-
// Section written by this version of the CLI.
|
|
49
|
-
const HEADERS = ['## astria', '# astria'];
|
|
50
|
-
// Sections written by pre-1.0 nodesify-graphify installs.
|
|
51
|
-
const LEGACY_HEADERS = ['## graphify', '# graphify'];
|
|
52
|
-
const LEGACY_SECTION_MARKER = '<!-- nodesify-graphify:managed -->';
|
|
53
|
-
const LEGACY_SECTION_SNIPPETS = [
|
|
54
|
-
// Current managed sections carry the old marker only; these fingerprints
|
|
55
|
-
// catch unmarked generated sections from earlier eras.
|
|
56
|
-
// "optional ... opt-in" wording (0.7.x-era)
|
|
57
|
-
'optional nodesify-graphify knowledge graph',
|
|
58
|
-
'maintained automatically after edits when the platform supports PostToolUse hooks',
|
|
59
|
-
// "MUST read" rules wording (early releases)
|
|
60
|
-
'MUST read .graphify/graph_report.md before searching files',
|
|
61
|
-
// "CRITICAL RULES / FORBIDDEN" wording
|
|
62
|
-
'**FORBIDDEN** from using native search tools',
|
|
63
|
-
];
|
|
64
|
-
function headingLevel(header) {
|
|
65
|
-
return (header.match(/^#+/) || ['#'])[0].length;
|
|
66
|
-
}
|
|
67
|
-
// Locate a section headed by `header` (matched at line start) and bounded
|
|
68
|
-
// by the next heading at the same or higher level, or EOF.
|
|
69
|
-
function findSection(existing, header) {
|
|
70
|
-
let start = existing.indexOf('\n' + header);
|
|
71
|
-
if (start === -1) {
|
|
72
|
-
if (!existing.startsWith(header))
|
|
73
|
-
return null;
|
|
74
|
-
start = 0;
|
|
75
|
-
}
|
|
76
|
-
const level = headingLevel(header);
|
|
77
|
-
const boundary = new RegExp(`\\n#{1,${level}} `);
|
|
78
|
-
const match = existing.slice(start + 1).match(boundary);
|
|
79
|
-
const end = match?.index !== undefined ? start + 1 + match.index : existing.length;
|
|
80
|
-
return { start, end };
|
|
81
|
-
}
|
|
82
|
-
function stripMarker(sectionText) {
|
|
83
|
-
return sectionText
|
|
84
|
-
.split('\n')
|
|
85
|
-
.filter((line) => {
|
|
86
|
-
const t = line.trim();
|
|
87
|
-
return t !== exports.SECTION_MARKER && t !== LEGACY_SECTION_MARKER;
|
|
88
|
-
})
|
|
89
|
-
.join('\n')
|
|
90
|
-
.trim();
|
|
91
|
-
}
|
|
92
|
-
function isManaged(sectionText) {
|
|
93
|
-
return (sectionText.includes(exports.SECTION_MARKER) ||
|
|
94
|
-
sectionText.includes(LEGACY_SECTION_MARKER) ||
|
|
95
|
-
LEGACY_SECTION_SNIPPETS.some((snippet) => sectionText.includes(snippet)));
|
|
96
|
-
}
|
|
97
|
-
function withMarker(content) {
|
|
98
|
-
return content.trimEnd() + '\n' + exports.SECTION_MARKER;
|
|
99
|
-
}
|
|
100
|
-
function injectSection(filePath, content) {
|
|
101
|
-
const dir = path.dirname(filePath);
|
|
102
|
-
if (!fs.existsSync(dir)) {
|
|
103
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
104
|
-
}
|
|
105
|
-
const existing = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf-8') : '';
|
|
106
|
-
// Refresh an existing astria section in place.
|
|
107
|
-
for (const h of HEADERS) {
|
|
108
|
-
const bounds = findSection(existing, h);
|
|
109
|
-
if (!bounds)
|
|
110
|
-
continue;
|
|
111
|
-
const sectionText = existing.slice(bounds.start, bounds.end);
|
|
112
|
-
if (stripMarker(sectionText) === content.trim())
|
|
113
|
-
return 'unchanged';
|
|
114
|
-
if (!isManaged(sectionText))
|
|
115
|
-
return 'unchanged';
|
|
116
|
-
fs.writeFileSync(filePath, existing.slice(0, bounds.start) + withMarker(content) + existing.slice(bounds.end), 'utf-8');
|
|
117
|
-
return 'updated';
|
|
118
|
-
}
|
|
119
|
-
// Upgrade a managed pre-1.0 graphify section to the astria wording. A
|
|
120
|
-
// user-customized graphify section is left untouched (treated as owned).
|
|
121
|
-
for (const h of LEGACY_HEADERS) {
|
|
122
|
-
const bounds = findSection(existing, h);
|
|
123
|
-
if (!bounds)
|
|
124
|
-
continue;
|
|
125
|
-
const sectionText = existing.slice(bounds.start, bounds.end);
|
|
126
|
-
if (!isManaged(sectionText))
|
|
127
|
-
return 'unchanged';
|
|
128
|
-
fs.writeFileSync(filePath, existing.slice(0, bounds.start) + withMarker(content) + existing.slice(bounds.end), 'utf-8');
|
|
129
|
-
return 'updated';
|
|
130
|
-
}
|
|
131
|
-
fs.writeFileSync(filePath, existing.replace(/\n*$/, '\n\n') + withMarker(content) + '\n', 'utf-8');
|
|
132
|
-
return 'added';
|
|
133
|
-
}
|
|
134
|
-
function removeSection(filePath) {
|
|
135
|
-
if (!fs.existsSync(filePath))
|
|
136
|
-
return false;
|
|
137
|
-
let content = fs.readFileSync(filePath, 'utf-8');
|
|
138
|
-
let changed = false;
|
|
139
|
-
for (const header of [...HEADERS, ...LEGACY_HEADERS]) {
|
|
140
|
-
let bounds = findSection(content, header);
|
|
141
|
-
while (bounds) {
|
|
142
|
-
content = content.slice(0, bounds.start) + content.slice(bounds.end);
|
|
143
|
-
changed = true;
|
|
144
|
-
bounds = findSection(content, header);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
if (!changed)
|
|
148
|
-
return false;
|
|
149
|
-
if (content.trim().length === 0) {
|
|
150
|
-
fs.unlinkSync(filePath);
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
fs.writeFileSync(filePath, content, 'utf-8');
|
|
154
|
-
}
|
|
155
|
-
return true;
|
|
156
|
-
}
|
|
157
|
-
exports.PROJECT_MD_SECTION = `## astria
|
|
158
|
-
|
|
159
|
-
This project has an astria knowledge graph at .astria/.
|
|
160
|
-
Access it through whichever path your agent has:
|
|
161
|
-
- MCP (when an astria MCP server is connected): repo_map, query_graph, explain,
|
|
162
|
-
get_neighbors, shortest_path, affected.
|
|
163
|
-
- CLI (works everywhere): astria map, query, explain, path, affected.
|
|
164
|
-
|
|
165
|
-
Always-on behaviors:
|
|
166
|
-
1. Prefer the graph over repeated text searches for architecture questions, feature
|
|
167
|
-
location, cross-file logic flow, and change impact; orient with repo_map (or map,
|
|
168
|
-
or .astria/graph_report.md), and run affected <node> before changing a shared symbol.
|
|
169
|
-
2. Before running grep/ripgrep to locate code, try astria query first --
|
|
170
|
-
it answers with file:line provenance in one call against the already-built graph.
|
|
171
|
-
3. After modifying code, run astria update . (AST-only, no API cost) so the
|
|
172
|
-
graph stays fresh; queries then report accurate staleness metadata.`;
|
|
173
|
-
exports.SKILL_REGISTRATION = `
|
|
174
|
-
# astria
|
|
175
|
-
- **astria** (\`~/.claude/skills/astria/SKILL.md\`) - any input to knowledge graph. Trigger: \`/astria\`
|
|
176
|
-
When the user types \`/astria\`, invoke the Skill tool with \`skill: "astria"\` before doing anything else.
|
|
177
|
-
`;
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.SKILL_REGISTRATION = exports.PROJECT_MD_SECTION = exports.SECTION_MARKER = void 0;
|
|
37
|
+
exports.injectSection = injectSection;
|
|
38
|
+
exports.removeSection = removeSection;
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
// Managed sections carry this marker so later installs can refresh them
|
|
42
|
+
// wholesale. Sections are recognized two ways: by this marker, or by a
|
|
43
|
+
// legacy fingerprint. Pre-1.0 installs wrote `## graphify` sections under
|
|
44
|
+
// the old `nodesify-graphify:managed` marker — install upgrades them in
|
|
45
|
+
// place and uninstall removes them. Anything else containing a heading is
|
|
46
|
+
// treated as user-owned and left untouched.
|
|
47
|
+
exports.SECTION_MARKER = '<!-- astria:managed -->';
|
|
48
|
+
// Section written by this version of the CLI.
|
|
49
|
+
const HEADERS = ['## astria', '# astria'];
|
|
50
|
+
// Sections written by pre-1.0 nodesify-graphify installs.
|
|
51
|
+
const LEGACY_HEADERS = ['## graphify', '# graphify'];
|
|
52
|
+
const LEGACY_SECTION_MARKER = '<!-- nodesify-graphify:managed -->';
|
|
53
|
+
const LEGACY_SECTION_SNIPPETS = [
|
|
54
|
+
// Current managed sections carry the old marker only; these fingerprints
|
|
55
|
+
// catch unmarked generated sections from earlier eras.
|
|
56
|
+
// "optional ... opt-in" wording (0.7.x-era)
|
|
57
|
+
'optional nodesify-graphify knowledge graph',
|
|
58
|
+
'maintained automatically after edits when the platform supports PostToolUse hooks',
|
|
59
|
+
// "MUST read" rules wording (early releases)
|
|
60
|
+
'MUST read .graphify/graph_report.md before searching files',
|
|
61
|
+
// "CRITICAL RULES / FORBIDDEN" wording
|
|
62
|
+
'**FORBIDDEN** from using native search tools',
|
|
63
|
+
];
|
|
64
|
+
function headingLevel(header) {
|
|
65
|
+
return (header.match(/^#+/) || ['#'])[0].length;
|
|
66
|
+
}
|
|
67
|
+
// Locate a section headed by `header` (matched at line start) and bounded
|
|
68
|
+
// by the next heading at the same or higher level, or EOF.
|
|
69
|
+
function findSection(existing, header) {
|
|
70
|
+
let start = existing.indexOf('\n' + header);
|
|
71
|
+
if (start === -1) {
|
|
72
|
+
if (!existing.startsWith(header))
|
|
73
|
+
return null;
|
|
74
|
+
start = 0;
|
|
75
|
+
}
|
|
76
|
+
const level = headingLevel(header);
|
|
77
|
+
const boundary = new RegExp(`\\n#{1,${level}} `);
|
|
78
|
+
const match = existing.slice(start + 1).match(boundary);
|
|
79
|
+
const end = match?.index !== undefined ? start + 1 + match.index : existing.length;
|
|
80
|
+
return { start, end };
|
|
81
|
+
}
|
|
82
|
+
function stripMarker(sectionText) {
|
|
83
|
+
return sectionText
|
|
84
|
+
.split('\n')
|
|
85
|
+
.filter((line) => {
|
|
86
|
+
const t = line.trim();
|
|
87
|
+
return t !== exports.SECTION_MARKER && t !== LEGACY_SECTION_MARKER;
|
|
88
|
+
})
|
|
89
|
+
.join('\n')
|
|
90
|
+
.trim();
|
|
91
|
+
}
|
|
92
|
+
function isManaged(sectionText) {
|
|
93
|
+
return (sectionText.includes(exports.SECTION_MARKER) ||
|
|
94
|
+
sectionText.includes(LEGACY_SECTION_MARKER) ||
|
|
95
|
+
LEGACY_SECTION_SNIPPETS.some((snippet) => sectionText.includes(snippet)));
|
|
96
|
+
}
|
|
97
|
+
function withMarker(content) {
|
|
98
|
+
return content.trimEnd() + '\n' + exports.SECTION_MARKER;
|
|
99
|
+
}
|
|
100
|
+
function injectSection(filePath, content) {
|
|
101
|
+
const dir = path.dirname(filePath);
|
|
102
|
+
if (!fs.existsSync(dir)) {
|
|
103
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
104
|
+
}
|
|
105
|
+
const existing = fs.existsSync(filePath) ? fs.readFileSync(filePath, 'utf-8') : '';
|
|
106
|
+
// Refresh an existing astria section in place.
|
|
107
|
+
for (const h of HEADERS) {
|
|
108
|
+
const bounds = findSection(existing, h);
|
|
109
|
+
if (!bounds)
|
|
110
|
+
continue;
|
|
111
|
+
const sectionText = existing.slice(bounds.start, bounds.end);
|
|
112
|
+
if (stripMarker(sectionText) === content.trim())
|
|
113
|
+
return 'unchanged';
|
|
114
|
+
if (!isManaged(sectionText))
|
|
115
|
+
return 'unchanged';
|
|
116
|
+
fs.writeFileSync(filePath, existing.slice(0, bounds.start) + withMarker(content) + existing.slice(bounds.end), 'utf-8');
|
|
117
|
+
return 'updated';
|
|
118
|
+
}
|
|
119
|
+
// Upgrade a managed pre-1.0 graphify section to the astria wording. A
|
|
120
|
+
// user-customized graphify section is left untouched (treated as owned).
|
|
121
|
+
for (const h of LEGACY_HEADERS) {
|
|
122
|
+
const bounds = findSection(existing, h);
|
|
123
|
+
if (!bounds)
|
|
124
|
+
continue;
|
|
125
|
+
const sectionText = existing.slice(bounds.start, bounds.end);
|
|
126
|
+
if (!isManaged(sectionText))
|
|
127
|
+
return 'unchanged';
|
|
128
|
+
fs.writeFileSync(filePath, existing.slice(0, bounds.start) + withMarker(content) + existing.slice(bounds.end), 'utf-8');
|
|
129
|
+
return 'updated';
|
|
130
|
+
}
|
|
131
|
+
fs.writeFileSync(filePath, existing.replace(/\n*$/, '\n\n') + withMarker(content) + '\n', 'utf-8');
|
|
132
|
+
return 'added';
|
|
133
|
+
}
|
|
134
|
+
function removeSection(filePath) {
|
|
135
|
+
if (!fs.existsSync(filePath))
|
|
136
|
+
return false;
|
|
137
|
+
let content = fs.readFileSync(filePath, 'utf-8');
|
|
138
|
+
let changed = false;
|
|
139
|
+
for (const header of [...HEADERS, ...LEGACY_HEADERS]) {
|
|
140
|
+
let bounds = findSection(content, header);
|
|
141
|
+
while (bounds) {
|
|
142
|
+
content = content.slice(0, bounds.start) + content.slice(bounds.end);
|
|
143
|
+
changed = true;
|
|
144
|
+
bounds = findSection(content, header);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (!changed)
|
|
148
|
+
return false;
|
|
149
|
+
if (content.trim().length === 0) {
|
|
150
|
+
fs.unlinkSync(filePath);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
fs.writeFileSync(filePath, content, 'utf-8');
|
|
154
|
+
}
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
exports.PROJECT_MD_SECTION = `## astria
|
|
158
|
+
|
|
159
|
+
This project has an astria knowledge graph at .astria/.
|
|
160
|
+
Access it through whichever path your agent has:
|
|
161
|
+
- MCP (when an astria MCP server is connected): repo_map, query_graph, explain,
|
|
162
|
+
get_neighbors, shortest_path, affected.
|
|
163
|
+
- CLI (works everywhere): astria map, query, explain, path, affected.
|
|
164
|
+
|
|
165
|
+
Always-on behaviors:
|
|
166
|
+
1. Prefer the graph over repeated text searches for architecture questions, feature
|
|
167
|
+
location, cross-file logic flow, and change impact; orient with repo_map (or map,
|
|
168
|
+
or .astria/graph_report.md), and run affected <node> before changing a shared symbol.
|
|
169
|
+
2. Before running grep/ripgrep to locate code, try astria query first --
|
|
170
|
+
it answers with file:line provenance in one call against the already-built graph.
|
|
171
|
+
3. After modifying code, run astria update . (AST-only, no API cost) so the
|
|
172
|
+
graph stays fresh; queries then report accurate staleness metadata.`;
|
|
173
|
+
exports.SKILL_REGISTRATION = `
|
|
174
|
+
# astria
|
|
175
|
+
- **astria** (\`~/.claude/skills/astria/SKILL.md\`) - any input to knowledge graph. Trigger: \`/astria\`
|
|
176
|
+
When the user types \`/astria\`, invoke the Skill tool with \`skill: "astria"\` before doing anything else.
|
|
177
|
+
`;
|
|
178
178
|
//# sourceMappingURL=markdown-inject.js.map
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
export interface PlatformConfig {
|
|
2
|
-
skillFile: string;
|
|
3
|
-
skillDst: string;
|
|
4
|
-
claudeMd: boolean;
|
|
5
|
-
agentsMd: boolean;
|
|
6
|
-
geminiMd: boolean;
|
|
7
|
-
settingsHook: 'claude' | 'codex' | 'gemini' | 'opencode' | 'none';
|
|
8
|
-
/** Register the astria MCP server in this platform's project-scoped config. */
|
|
9
|
-
mcp?: 'zcode' | 'claude' | 'cursor' | 'gemini';
|
|
10
|
-
}
|
|
11
|
-
export declare const PLATFORMS: Record<string, PlatformConfig>;
|
|
12
|
-
export declare const PLATFORM_NAMES: string[];
|
|
1
|
+
export interface PlatformConfig {
|
|
2
|
+
skillFile: string;
|
|
3
|
+
skillDst: string;
|
|
4
|
+
claudeMd: boolean;
|
|
5
|
+
agentsMd: boolean;
|
|
6
|
+
geminiMd: boolean;
|
|
7
|
+
settingsHook: 'claude' | 'codex' | 'gemini' | 'opencode' | 'none';
|
|
8
|
+
/** Register the astria MCP server in this platform's project-scoped config. */
|
|
9
|
+
mcp?: 'zcode' | 'claude' | 'cursor' | 'gemini';
|
|
10
|
+
}
|
|
11
|
+
export declare const PLATFORMS: Record<string, PlatformConfig>;
|
|
12
|
+
export declare const PLATFORM_NAMES: string[];
|
|
13
13
|
//# sourceMappingURL=platforms.d.ts.map
|