archgraph-argo 0.10.43 → 0.10.44
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 +201 -201
- package/argo/package.json +8 -8
- package/argo/schema/ImplementationToCodingHandoff.schema.json +251 -251
- package/argo/schema/ImplementationToIntentTraceProposal.schema.json +180 -180
- package/argo/schema/IntentToImplementationHandoff.schema.json +74 -74
- package/argo/schema/SystemArchitecture.schema.json +378 -378
- package/argo/schema/archimate3.2.md +7153 -7153
- package/argo/scripts/archimate32-rules.js +12301 -12301
- package/argo/scripts/generateArchitectureDiffPlantuml.js +466 -466
- package/argo/scripts/graph-rag/ARCHITECTURE.md +192 -192
- package/argo/scripts/graph-rag/canonicalProjectionAuthority.js +45 -45
- package/argo/scripts/graph-rag/embeddingQualificationGate.js +59 -59
- package/argo/scripts/graph-rag/externalProductionConfig.js +74 -74
- package/argo/scripts/graph-rag/liveEmbeddingProviderClient.js +49 -49
- package/argo/scripts/graph-rag/neo4jNativeRetrieval.js +37 -37
- package/argo/scripts/graph-rag/semantic-persistence/ARCHITECTURE.md +51 -51
- package/argo/scripts/graph-rag/semantic-persistence/productionSemanticCheckpointStore.js +99 -99
- package/argo/scripts/graph-rag/semantic-persistence/productionSemanticProjectionStore.js +171 -171
- package/argo/scripts/graph-rag/semanticOperatorError.js +38 -38
- package/argo/scripts/graph-rag/semanticOperatorJourney.js +459 -459
- package/argo/scripts/graph-rag/semanticReadinessAttestationStore.js +398 -398
- package/argo/scripts/graph-rag/systemMetadataCommandAdapter.js +269 -269
- package/argo/scripts/graph-semantics.js +220 -220
- package/argo/scripts/repositoryArgoEnvironment.js +101 -101
- package/argo/scripts/runArchitectureTests.js +583 -583
- package/argo/scripts/semanticOperatorJourneyCli.js +91 -91
- package/argo/scripts/syncSystemArchitectureToNeo4j.js +66 -66
- package/argo/scripts/test-executors/_template.js +58 -58
- package/argo/scripts/test-executors/default.js +199 -199
- package/argo/scripts/validateStageHandoff.js +458 -458
- package/argo/scripts/validateSystemArchitecture.js +253 -253
- package/argo/scripts/validateTraceProposal.js +181 -181
- package/bin/argo-deploy.js +12 -12
- package/install-argo.ps1 +27 -8
- package/package.json +1 -1
|
@@ -1,181 +1,181 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
const {
|
|
5
|
-
getArgoRoot,
|
|
6
|
-
getWorkspaceRoot,
|
|
7
|
-
} = require('./argo-paths.js');
|
|
8
|
-
|
|
9
|
-
const repoRoot = getWorkspaceRoot();
|
|
10
|
-
const DEFAULT_PROPOSAL_PATH = 'design/KG/ImplementationToIntentTraceProposal.json';
|
|
11
|
-
const TRACE_PROPOSAL_SCHEMA_PATH = '.argo/schema/ImplementationToIntentTraceProposal.schema.json';
|
|
12
|
-
|
|
13
|
-
function main() {
|
|
14
|
-
const proposalPath = process.argv[2] || DEFAULT_PROPOSAL_PATH;
|
|
15
|
-
const errors = validateTraceProposal(proposalPath);
|
|
16
|
-
|
|
17
|
-
if (errors.length > 0) {
|
|
18
|
-
console.error('Trace proposal validation failed:');
|
|
19
|
-
for (const error of errors) {
|
|
20
|
-
console.error(`- ${error}`);
|
|
21
|
-
}
|
|
22
|
-
process.exit(1);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
console.log(`Trace proposal validation passed for: ${proposalPath}`);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function resolveSchemaAbsolutePath(schemaPath) {
|
|
29
|
-
const bundledCandidate = path.join(getArgoRoot(), 'schema', path.basename(schemaPath));
|
|
30
|
-
if (fs.existsSync(bundledCandidate)) {
|
|
31
|
-
return bundledCandidate;
|
|
32
|
-
}
|
|
33
|
-
return path.join(repoRoot, schemaPath);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function validateTraceProposal(proposalPath) {
|
|
37
|
-
const errors = [];
|
|
38
|
-
const schemaAbsolutePath = resolveSchemaAbsolutePath(TRACE_PROPOSAL_SCHEMA_PATH);
|
|
39
|
-
if (!fs.existsSync(schemaAbsolutePath)) {
|
|
40
|
-
errors.push(`schema file is missing at ${TRACE_PROPOSAL_SCHEMA_PATH}`);
|
|
41
|
-
return errors;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const proposalAbsolutePath = path.join(repoRoot, proposalPath.replace(/[\\/]+/g, path.sep));
|
|
45
|
-
if (!fs.existsSync(proposalAbsolutePath)) {
|
|
46
|
-
errors.push(`proposal file is missing at ${proposalPath}`);
|
|
47
|
-
return errors;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const document = readJson(proposalAbsolutePath, proposalPath, errors);
|
|
51
|
-
if (!document) {
|
|
52
|
-
return errors;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
requireExact(document, 'proposalType', 'implementation-to-intent-trace', errors, proposalPath);
|
|
56
|
-
requireString(document, 'generatedAt', errors, proposalPath);
|
|
57
|
-
requireExact(document, 'sourceAgent', 'ImplementationDesign', errors, proposalPath);
|
|
58
|
-
requireExact(document, 'targetAgent', 'IntentionDesign', errors, proposalPath);
|
|
59
|
-
requireExact(document, 'lifecycle', 'temporary-trace-proposal', errors, proposalPath);
|
|
60
|
-
|
|
61
|
-
const graphPath = requireString(document, 'sourceIntentGraphPath', errors, proposalPath);
|
|
62
|
-
if (graphPath) {
|
|
63
|
-
ensureRepoPathExists(graphPath, `${proposalPath}.sourceIntentGraphPath`, errors);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const implementationContracts = requireStringArray(document, 'implementationContracts', true, errors, proposalPath);
|
|
67
|
-
if (Array.isArray(implementationContracts)) {
|
|
68
|
-
implementationContracts.forEach((contractPath, index) => {
|
|
69
|
-
ensureRepoPathExists(contractPath, `${proposalPath}.implementationContracts[${index}]`, errors);
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const anchorProposals = requireArray(document, 'anchorProposals', true, errors, proposalPath);
|
|
74
|
-
if (Array.isArray(anchorProposals)) {
|
|
75
|
-
anchorProposals.forEach((anchor, index) => validateAnchorProposal(anchor, `${proposalPath}.anchorProposals[${index}]`, errors));
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return errors;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
function validateAnchorProposal(anchor, prefix, errors) {
|
|
82
|
-
requireString(anchor, 'intentElementId', errors, prefix);
|
|
83
|
-
requireString(anchor, 'implementationElementName', errors, prefix);
|
|
84
|
-
const implementationElementKind = requireString(anchor, 'implementationElementKind', errors, prefix);
|
|
85
|
-
if (implementationElementKind && ![
|
|
86
|
-
'stable-directory',
|
|
87
|
-
'contract-file',
|
|
88
|
-
'explicit-test-entry',
|
|
89
|
-
'critical-guardrail',
|
|
90
|
-
'runtime-component',
|
|
91
|
-
'schema-contract',
|
|
92
|
-
'mcp-tool',
|
|
93
|
-
'command',
|
|
94
|
-
].includes(implementationElementKind)) {
|
|
95
|
-
errors.push(`${prefix}.implementationElementKind has unsupported value '${implementationElementKind}'`);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
const implementsType = requireString(anchor, 'implementsType', errors, prefix);
|
|
99
|
-
if (implementsType && !['direct', 'indirect'].includes(implementsType)) {
|
|
100
|
-
errors.push(`${prefix}.implementsType must be 'direct' or 'indirect'`);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
requireString(anchor, 'tracePurpose', errors, prefix);
|
|
104
|
-
const contractPaths = requireStringArray(anchor, 'contractPaths', true, errors, prefix);
|
|
105
|
-
if (Array.isArray(contractPaths)) {
|
|
106
|
-
contractPaths.forEach((contractPath, index) => {
|
|
107
|
-
ensureRepoPathExists(contractPath, `${prefix}.contractPaths[${index}]`, errors);
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
const contextEntryPoints = requireStringArray(anchor, 'contextEntryPoints', true, errors, prefix);
|
|
111
|
-
if (Array.isArray(contextEntryPoints)) {
|
|
112
|
-
contextEntryPoints.forEach((entryPoint, index) => {
|
|
113
|
-
ensureRepoPathExists(entryPoint, `${prefix}.contextEntryPoints[${index}]`, errors);
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
requireStringArray(anchor, 'excludedDetails', true, errors, prefix);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function readJson(filePath, label, errors) {
|
|
120
|
-
try {
|
|
121
|
-
return JSON.parse(fs.readFileSync(filePath, 'utf8').replace(/^\uFEFF/, ''));
|
|
122
|
-
} catch (error) {
|
|
123
|
-
errors.push(`failed to parse ${label}: ${String(error)}`);
|
|
124
|
-
return undefined;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function requireExact(object, key, expectedValue, errors, prefix) {
|
|
129
|
-
const value = requireString(object, key, errors, prefix);
|
|
130
|
-
if (value && value !== expectedValue) {
|
|
131
|
-
errors.push(`${prefix}.${key} must be '${expectedValue}'`);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function requireString(object, key, errors, prefix) {
|
|
136
|
-
if (!object || typeof object[key] !== 'string' || object[key].trim() === '') {
|
|
137
|
-
errors.push(`${prefix}.${key} must be a non-empty string`);
|
|
138
|
-
return undefined;
|
|
139
|
-
}
|
|
140
|
-
return object[key];
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function requireArray(object, key, mustHaveItems, errors, prefix) {
|
|
144
|
-
if (!object || !Array.isArray(object[key])) {
|
|
145
|
-
errors.push(`${prefix}.${key} must be an array`);
|
|
146
|
-
return undefined;
|
|
147
|
-
}
|
|
148
|
-
if (mustHaveItems && object[key].length === 0) {
|
|
149
|
-
errors.push(`${prefix}.${key} must not be empty`);
|
|
150
|
-
}
|
|
151
|
-
return object[key];
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
function requireStringArray(object, key, mustHaveItems, errors, prefix) {
|
|
155
|
-
const value = requireArray(object, key, mustHaveItems, errors, prefix);
|
|
156
|
-
if (!Array.isArray(value)) {
|
|
157
|
-
return undefined;
|
|
158
|
-
}
|
|
159
|
-
value.forEach((entry, index) => {
|
|
160
|
-
if (typeof entry !== 'string' || entry.trim() === '') {
|
|
161
|
-
errors.push(`${prefix}.${key}[${index}] must be a non-empty string`);
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
return value;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
function ensureRepoPathExists(relativePath, label, errors) {
|
|
168
|
-
const normalized = relativePath.replace(/[\\/]+/g, path.sep);
|
|
169
|
-
const absolutePath = path.join(repoRoot, normalized);
|
|
170
|
-
if (!fs.existsSync(absolutePath)) {
|
|
171
|
-
errors.push(`${label} points to a missing path: ${relativePath}`);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (require.main === module) {
|
|
176
|
-
main();
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
module.exports = {
|
|
180
|
-
validateTraceProposal,
|
|
181
|
-
};
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const {
|
|
5
|
+
getArgoRoot,
|
|
6
|
+
getWorkspaceRoot,
|
|
7
|
+
} = require('./argo-paths.js');
|
|
8
|
+
|
|
9
|
+
const repoRoot = getWorkspaceRoot();
|
|
10
|
+
const DEFAULT_PROPOSAL_PATH = 'design/KG/ImplementationToIntentTraceProposal.json';
|
|
11
|
+
const TRACE_PROPOSAL_SCHEMA_PATH = '.argo/schema/ImplementationToIntentTraceProposal.schema.json';
|
|
12
|
+
|
|
13
|
+
function main() {
|
|
14
|
+
const proposalPath = process.argv[2] || DEFAULT_PROPOSAL_PATH;
|
|
15
|
+
const errors = validateTraceProposal(proposalPath);
|
|
16
|
+
|
|
17
|
+
if (errors.length > 0) {
|
|
18
|
+
console.error('Trace proposal validation failed:');
|
|
19
|
+
for (const error of errors) {
|
|
20
|
+
console.error(`- ${error}`);
|
|
21
|
+
}
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
console.log(`Trace proposal validation passed for: ${proposalPath}`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function resolveSchemaAbsolutePath(schemaPath) {
|
|
29
|
+
const bundledCandidate = path.join(getArgoRoot(), 'schema', path.basename(schemaPath));
|
|
30
|
+
if (fs.existsSync(bundledCandidate)) {
|
|
31
|
+
return bundledCandidate;
|
|
32
|
+
}
|
|
33
|
+
return path.join(repoRoot, schemaPath);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function validateTraceProposal(proposalPath) {
|
|
37
|
+
const errors = [];
|
|
38
|
+
const schemaAbsolutePath = resolveSchemaAbsolutePath(TRACE_PROPOSAL_SCHEMA_PATH);
|
|
39
|
+
if (!fs.existsSync(schemaAbsolutePath)) {
|
|
40
|
+
errors.push(`schema file is missing at ${TRACE_PROPOSAL_SCHEMA_PATH}`);
|
|
41
|
+
return errors;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const proposalAbsolutePath = path.join(repoRoot, proposalPath.replace(/[\\/]+/g, path.sep));
|
|
45
|
+
if (!fs.existsSync(proposalAbsolutePath)) {
|
|
46
|
+
errors.push(`proposal file is missing at ${proposalPath}`);
|
|
47
|
+
return errors;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const document = readJson(proposalAbsolutePath, proposalPath, errors);
|
|
51
|
+
if (!document) {
|
|
52
|
+
return errors;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
requireExact(document, 'proposalType', 'implementation-to-intent-trace', errors, proposalPath);
|
|
56
|
+
requireString(document, 'generatedAt', errors, proposalPath);
|
|
57
|
+
requireExact(document, 'sourceAgent', 'ImplementationDesign', errors, proposalPath);
|
|
58
|
+
requireExact(document, 'targetAgent', 'IntentionDesign', errors, proposalPath);
|
|
59
|
+
requireExact(document, 'lifecycle', 'temporary-trace-proposal', errors, proposalPath);
|
|
60
|
+
|
|
61
|
+
const graphPath = requireString(document, 'sourceIntentGraphPath', errors, proposalPath);
|
|
62
|
+
if (graphPath) {
|
|
63
|
+
ensureRepoPathExists(graphPath, `${proposalPath}.sourceIntentGraphPath`, errors);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const implementationContracts = requireStringArray(document, 'implementationContracts', true, errors, proposalPath);
|
|
67
|
+
if (Array.isArray(implementationContracts)) {
|
|
68
|
+
implementationContracts.forEach((contractPath, index) => {
|
|
69
|
+
ensureRepoPathExists(contractPath, `${proposalPath}.implementationContracts[${index}]`, errors);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const anchorProposals = requireArray(document, 'anchorProposals', true, errors, proposalPath);
|
|
74
|
+
if (Array.isArray(anchorProposals)) {
|
|
75
|
+
anchorProposals.forEach((anchor, index) => validateAnchorProposal(anchor, `${proposalPath}.anchorProposals[${index}]`, errors));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return errors;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function validateAnchorProposal(anchor, prefix, errors) {
|
|
82
|
+
requireString(anchor, 'intentElementId', errors, prefix);
|
|
83
|
+
requireString(anchor, 'implementationElementName', errors, prefix);
|
|
84
|
+
const implementationElementKind = requireString(anchor, 'implementationElementKind', errors, prefix);
|
|
85
|
+
if (implementationElementKind && ![
|
|
86
|
+
'stable-directory',
|
|
87
|
+
'contract-file',
|
|
88
|
+
'explicit-test-entry',
|
|
89
|
+
'critical-guardrail',
|
|
90
|
+
'runtime-component',
|
|
91
|
+
'schema-contract',
|
|
92
|
+
'mcp-tool',
|
|
93
|
+
'command',
|
|
94
|
+
].includes(implementationElementKind)) {
|
|
95
|
+
errors.push(`${prefix}.implementationElementKind has unsupported value '${implementationElementKind}'`);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const implementsType = requireString(anchor, 'implementsType', errors, prefix);
|
|
99
|
+
if (implementsType && !['direct', 'indirect'].includes(implementsType)) {
|
|
100
|
+
errors.push(`${prefix}.implementsType must be 'direct' or 'indirect'`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
requireString(anchor, 'tracePurpose', errors, prefix);
|
|
104
|
+
const contractPaths = requireStringArray(anchor, 'contractPaths', true, errors, prefix);
|
|
105
|
+
if (Array.isArray(contractPaths)) {
|
|
106
|
+
contractPaths.forEach((contractPath, index) => {
|
|
107
|
+
ensureRepoPathExists(contractPath, `${prefix}.contractPaths[${index}]`, errors);
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
const contextEntryPoints = requireStringArray(anchor, 'contextEntryPoints', true, errors, prefix);
|
|
111
|
+
if (Array.isArray(contextEntryPoints)) {
|
|
112
|
+
contextEntryPoints.forEach((entryPoint, index) => {
|
|
113
|
+
ensureRepoPathExists(entryPoint, `${prefix}.contextEntryPoints[${index}]`, errors);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
requireStringArray(anchor, 'excludedDetails', true, errors, prefix);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function readJson(filePath, label, errors) {
|
|
120
|
+
try {
|
|
121
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf8').replace(/^\uFEFF/, ''));
|
|
122
|
+
} catch (error) {
|
|
123
|
+
errors.push(`failed to parse ${label}: ${String(error)}`);
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function requireExact(object, key, expectedValue, errors, prefix) {
|
|
129
|
+
const value = requireString(object, key, errors, prefix);
|
|
130
|
+
if (value && value !== expectedValue) {
|
|
131
|
+
errors.push(`${prefix}.${key} must be '${expectedValue}'`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function requireString(object, key, errors, prefix) {
|
|
136
|
+
if (!object || typeof object[key] !== 'string' || object[key].trim() === '') {
|
|
137
|
+
errors.push(`${prefix}.${key} must be a non-empty string`);
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
return object[key];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function requireArray(object, key, mustHaveItems, errors, prefix) {
|
|
144
|
+
if (!object || !Array.isArray(object[key])) {
|
|
145
|
+
errors.push(`${prefix}.${key} must be an array`);
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
if (mustHaveItems && object[key].length === 0) {
|
|
149
|
+
errors.push(`${prefix}.${key} must not be empty`);
|
|
150
|
+
}
|
|
151
|
+
return object[key];
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function requireStringArray(object, key, mustHaveItems, errors, prefix) {
|
|
155
|
+
const value = requireArray(object, key, mustHaveItems, errors, prefix);
|
|
156
|
+
if (!Array.isArray(value)) {
|
|
157
|
+
return undefined;
|
|
158
|
+
}
|
|
159
|
+
value.forEach((entry, index) => {
|
|
160
|
+
if (typeof entry !== 'string' || entry.trim() === '') {
|
|
161
|
+
errors.push(`${prefix}.${key}[${index}] must be a non-empty string`);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
return value;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function ensureRepoPathExists(relativePath, label, errors) {
|
|
168
|
+
const normalized = relativePath.replace(/[\\/]+/g, path.sep);
|
|
169
|
+
const absolutePath = path.join(repoRoot, normalized);
|
|
170
|
+
if (!fs.existsSync(absolutePath)) {
|
|
171
|
+
errors.push(`${label} points to a missing path: ${relativePath}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (require.main === module) {
|
|
176
|
+
main();
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
module.exports = {
|
|
180
|
+
validateTraceProposal,
|
|
181
|
+
};
|
package/bin/argo-deploy.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
const { spawnSync } = require('node:child_process');
|
|
5
|
-
const path = require('node:path');
|
|
6
|
-
|
|
7
|
-
const script = path.join(__dirname, '..', 'install-argo.ps1');
|
|
8
|
-
const shell = process.platform === 'win32' ? 'powershell' : 'pwsh';
|
|
9
|
-
const args = ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', script, ...process.argv.slice(2)];
|
|
10
|
-
|
|
11
|
-
const result = spawnSync(shell, args, { stdio: 'inherit' });
|
|
12
|
-
process.exit(result.status === null ? 1 : result.status);
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const { spawnSync } = require('node:child_process');
|
|
5
|
+
const path = require('node:path');
|
|
6
|
+
|
|
7
|
+
const script = path.join(__dirname, '..', 'install-argo.ps1');
|
|
8
|
+
const shell = process.platform === 'win32' ? 'powershell' : 'pwsh';
|
|
9
|
+
const args = ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', script, ...process.argv.slice(2)];
|
|
10
|
+
|
|
11
|
+
const result = spawnSync(shell, args, { stdio: 'inherit' });
|
|
12
|
+
process.exit(result.status === null ? 1 : result.status);
|
package/install-argo.ps1
CHANGED
|
@@ -24,7 +24,8 @@ param(
|
|
|
24
24
|
[string]$OpenClawWorkspace = "$env:USERPROFILE\.openclaw\workspace",
|
|
25
25
|
[string]$OpenClawRepoRoot = '',
|
|
26
26
|
[switch]$SkipOpenClaw,
|
|
27
|
-
[string]$McpPath
|
|
27
|
+
[string]$McpPath,
|
|
28
|
+
[string]$GraphMcpUrl = 'https://argo.derekworkspacev5.com/mcp'
|
|
28
29
|
)
|
|
29
30
|
|
|
30
31
|
$ErrorActionPreference = 'Stop'
|
|
@@ -135,7 +136,8 @@ function Write-McpConfig {
|
|
|
135
136
|
param(
|
|
136
137
|
[string]$Path,
|
|
137
138
|
[string]$ServersKey,
|
|
138
|
-
$ServerConfig
|
|
139
|
+
$ServerConfig,
|
|
140
|
+
[System.Collections.IDictionary]$ExtraServers = $null
|
|
139
141
|
)
|
|
140
142
|
|
|
141
143
|
$root = [ordered]@{}
|
|
@@ -160,6 +162,11 @@ function Write-McpConfig {
|
|
|
160
162
|
}
|
|
161
163
|
}
|
|
162
164
|
$servers['argo'] = $ServerConfig
|
|
165
|
+
if ($null -ne $ExtraServers) {
|
|
166
|
+
foreach ($name in $ExtraServers.Keys) {
|
|
167
|
+
$servers[$name] = $ExtraServers[$name]
|
|
168
|
+
}
|
|
169
|
+
}
|
|
163
170
|
$root[$ServersKey] = $servers
|
|
164
171
|
|
|
165
172
|
New-Item -ItemType Directory -Force -Path (Split-Path $Path) | Out-Null
|
|
@@ -346,7 +353,8 @@ function Write-OpenClawMcpConfig {
|
|
|
346
353
|
param(
|
|
347
354
|
[string]$OpenClawHome,
|
|
348
355
|
[string]$RepoRoot,
|
|
349
|
-
[string]$ArgoServer
|
|
356
|
+
[string]$ArgoServer,
|
|
357
|
+
$GraphMcpServer
|
|
350
358
|
)
|
|
351
359
|
$configPath = Join-Path $OpenClawHome 'openclaw.json'
|
|
352
360
|
$root = [ordered]@{}
|
|
@@ -408,6 +416,9 @@ function Write-OpenClawMcpConfig {
|
|
|
408
416
|
$argoServerObj.env = $envBlock
|
|
409
417
|
}
|
|
410
418
|
$servers['argo'] = $argoServerObj
|
|
419
|
+
if ($null -ne $GraphMcpServer) {
|
|
420
|
+
$servers['graph-mcp'] = $GraphMcpServer
|
|
421
|
+
}
|
|
411
422
|
$mcp['servers'] = $servers
|
|
412
423
|
$root['mcp'] = $mcp
|
|
413
424
|
New-Item -ItemType Directory -Force -Path $OpenClawHome | Out-Null
|
|
@@ -836,7 +847,10 @@ if ($SkipDsh) {
|
|
|
836
847
|
Write-Host "[19/22] argo\agents -> $DshHome\.agent-presets\<id> (DeepSeek Harness agent presets)"
|
|
837
848
|
New-DshAgentPresets -DshHome $DshHome -AgentsSrc (Join-Path $argoDir 'agents')
|
|
838
849
|
|
|
839
|
-
Write-Host
|
|
850
|
+
Write-Host " note: graph-mcp remote ($GraphMcpUrl) is NOT registered for DeepSeek Harness -"
|
|
851
|
+
Write-Host " ~/.dsh/cordis.patch.yml only carries plugin rows (the dsh-argo-workspace bridge spawns"
|
|
852
|
+
Write-Host " the local argo server); an HTTP remote MCP server has no equivalent cordis row here."
|
|
853
|
+
Write-Host " Restart `dsh web` to activate the MCP bridge and the wakeup plugin;"
|
|
840
854
|
Write-Host ' new sessions pick up the global rule and the argo-init skill automatically.'
|
|
841
855
|
Write-Host ' The argo tools (mcp__argo__*) auto-follow the workspace the user switched to'
|
|
842
856
|
Write-Host ' in one dsh instance - no restart needed between workspaces (the server honors'
|
|
@@ -956,6 +970,11 @@ if ($SkipMcp) {
|
|
|
956
970
|
Write-Host 'Skipped MCP configuration (-SkipMcp).'
|
|
957
971
|
} else {
|
|
958
972
|
$argoServer = (Join-Path $ArgoRoot 'scripts\argo-mcp-server.js').Replace('\', '/')
|
|
973
|
+
$graphMcpServer = [ordered]@{
|
|
974
|
+
type = 'remote'
|
|
975
|
+
url = $GraphMcpUrl
|
|
976
|
+
enabled = $true
|
|
977
|
+
}
|
|
959
978
|
|
|
960
979
|
Write-Host '==> Registering argo MCP server in VS Code (GitHub Copilot)'
|
|
961
980
|
$mcpPath = if ($McpPath) { $McpPath } else { Join-Path $env:APPDATA 'Code\User\mcp.json' }
|
|
@@ -963,7 +982,7 @@ if ($SkipMcp) {
|
|
|
963
982
|
type = 'stdio'
|
|
964
983
|
command = 'node'
|
|
965
984
|
args = @($argoServer)
|
|
966
|
-
})
|
|
985
|
+
}) -ExtraServers ([ordered]@{ 'graph-mcp' = $graphMcpServer })
|
|
967
986
|
Write-Host "argo MCP config written -> $mcpPath"
|
|
968
987
|
|
|
969
988
|
Write-Host '==> Registering argo MCP server in Cursor'
|
|
@@ -971,7 +990,7 @@ if ($SkipMcp) {
|
|
|
971
990
|
type = 'stdio'
|
|
972
991
|
command = 'node'
|
|
973
992
|
args = @($argoServer)
|
|
974
|
-
})
|
|
993
|
+
}) -ExtraServers ([ordered]@{ 'graph-mcp' = $graphMcpServer })
|
|
975
994
|
Write-Host "argo MCP config written -> $CursorMcpPath"
|
|
976
995
|
|
|
977
996
|
Write-Host '==> Registering argo MCP server in OpenCode'
|
|
@@ -979,7 +998,7 @@ if ($SkipMcp) {
|
|
|
979
998
|
type = 'local'
|
|
980
999
|
command = @('node', $argoServer)
|
|
981
1000
|
enabled = $true
|
|
982
|
-
})
|
|
1001
|
+
}) -ExtraServers ([ordered]@{ 'graph-mcp' = $graphMcpServer })
|
|
983
1002
|
Write-Host "argo MCP config written -> $OpenCodeConfigPath"
|
|
984
1003
|
|
|
985
1004
|
if (-not $SkipOpenClaw) {
|
|
@@ -988,7 +1007,7 @@ if ($SkipMcp) {
|
|
|
988
1007
|
# installer runs from a non-workspace npm-global package dir).
|
|
989
1008
|
$openClawRepoRoot = if ($OpenClawRepoRoot) { $OpenClawRepoRoot } else { $repoRoot }
|
|
990
1009
|
Write-Host "[22/22] argo MCP server -> $(Join-Path $OpenClawHome 'openclaw.json') (OpenClaw mcp.servers.argo, env.ARGO_REPO_ROOT pinned)"
|
|
991
|
-
Write-OpenClawMcpConfig -OpenClawHome $OpenClawHome -RepoRoot $openClawRepoRoot -ArgoServer $argoServer
|
|
1010
|
+
Write-OpenClawMcpConfig -OpenClawHome $OpenClawHome -RepoRoot $openClawRepoRoot -ArgoServer $argoServer -GraphMcpServer $graphMcpServer
|
|
992
1011
|
}
|
|
993
1012
|
}
|
|
994
1013
|
|
package/package.json
CHANGED